Reformat Custom Date in PHP - php

So I know how to format a date in PHP, but not from a custom format. I have a date that is a string "YYMMDD" and I want to make it "MMDDYYYY'. strtotime doesn't seem like it would do a good job of this when the MM and DD are both low digits.

Use str_split:
$date1 = "YYMMDD";
list($yy, $mm, $dd) = str_split($date1, 2);
// MMDDYYYY format, assuming they are all > 2000
$date2 = $mm . $dd . "20" . $yy;

If you're running PHP >= 5.3, have a look at DateTime::createFromFormat. Otherwise, if you don't want to use pure string manipulation techniques, use the more primitive strptime together with mktime to parse the time into a UNIX timestamp, which you can then format using date.

Maybe I am under-thinking this, but couldn't you just:
$oldDate='040220'; // February 20th, 2004
$year = substr($oldDate, 0,2);
$year += $year &lt 50 ? 2000 : 1900;
$date = preg_replace('/\d{2}(\d{2})(\d{2})/', '$1/$3/'.$year, $oldDate);
And you'd have the string you were looking for, or something close enough to it that you could modify from what I wrote here.

Have many dates prior to 1910? If not, you could check your YY for <=10, and if true, prepend "20" else prepend "19"... Kinda similar approach to MM and DD check for <10 and prepend a "0" if true... (This is all after exploding, or substring... Assign each part to its own variable, i.e. $M=$MM; $D=$DD; $Y=$YYYY; then concatenate/arrange in whatever order you want... Just another potential way to skin the proverbial cat...

Ended up doing:
$expiration_date_year = substr($matches['expiration_date'],0,2);
$expiration_date_month = substr($matches['expiration_date'],2,2);
$expiration_date_day = substr($matches['expiration_date'],4,2);
$expiration_date = date('m/d/Y', mktime(0,0,0,$expiration_date_month, $expiration_date_day, $expiration_date_year));

Related

Converting a non standard date string to a mysql datetime string using php

My intention is to convert the following date
20/04/17 13:27:5
to this
20-04-2017 13:27:05
I tried the typical date format functions of php and also Carbon...
things like
$newDate= Carbon::createFromFormat('d/m/y H:m:s', $originalDate);
in this case
var_dump($newDate->toDateTimeString()) would bring 2019-03-20 13:00:55 which is not what I expect.
So I was not lucky....is there a way to do this in a straight forward manner?
I think this should work.
$date = "20/04/17 13:27:5";
$sec = substr($date, strrpos($date, ":") + 1);
$sec = substr("0{$sec}", -2);
$new = substr($date, 0, strrpos($date, ":") + 1) . $sec;
$newDate = Carbon::createFromFormat('d/m/y H:i:s', $new);
I changed the format since you were using m twice for "minutes" and "month". It is correct for the month, but not for the minutes. Instead use i for minutes with leading zeroes.
$sec Is what I used to get the second from the string. This gets the last position of : and will take everything after it. This assumes that you do not change the format of the string.
substr("0{$sec}", -2) Adds a zero to the current second and extracts the last two characters. That means that 50 becomes 050 and then the last two characters are 50 so we end up without the padding, but 5 becomes 05 and the last two characters are the only characters.
$new concatenates the start of the date string and the new second with the zero padding.
$newDate is your original string with the format changed.
There is issue with seconds. There must be 05 not only 5
<?php
$original_date = "20/04/17 13:27:5";
$date_explode = explode(":", $original_date);
$date_explode[2] = str_pad($date_explode[2],2,"0",STR_PAD_LEFT);
$original_date = implode($date_explode,":");
$date = DateTime::createFromFormat('d/m/y H:i:s', $original_date);
echo date_format($date,"d-m-Y H:i:s");
?>
This is a working conversion routine that creates the ISO format you are looking for. But as already mentioned you need to "fix" the strange way the seconds are specified in the original example you provide. You will have to use string functions if that really is the format you receive. Better would be to fix the code that creates such broken formats.
<?php
$input = '20/04/17 13:27:05';
$date = DateTime::createFromFormat('d/m/y H:i:s', $input);
var_dump($date->format('d-m-Y H:i:s'));
The output obviously is:
string(19) "20-04-2017 13:27:05"
Isn't it like this?
$newDate = Carbon::createFromFormat('d/m/y H:i:s', $originalDate);

Date format in float from Persavise db

I got data from a Persavive V12 Db. The dates are in a weird format.
They are like float :
Example of date in table : 39787.0
Do someone know this kind of format ? It seems to be the number of days from 1901-01-01.
Since the dates are float, is it possible to add days from a date in PHP ? Like :
$from = '1901-01-01';
$date = date('Y-m-d', strtotime($from .' +'. $float .' days'));
I got always 1970-01-01. Is there another way ?
My first answer so don't hurt me much.
I'm not quite sure what you want to do (put back in the database or perform further operations so I only posted one solution)
The number you posted 39787.0 is a unix timestamp. You need to use mktime to convert what you want to a number (And you need date to convert it to a readable form). Since mktime uses 1901-01-01 as a starting date as well you have to make a couple of changes.
I was a biz lazy and didn't include all the code for all fields but this should allow you modify to add whatever you want (and possibly clean it up to a single line if you want).
I made it in long form so it's easy to read.
<?
$olddate = 39787.0;
$hour = 0;
$min = 0;
$sec = 0;
$month = 0;
$year = 0;
$day = 12;
$month += date("m",$olddate);
$day += date("d",$olddate);
$year += date("Y",$olddate);
$x = date("Ymd",mktime($hour,$min,$sec,$month,$day,$year));
echo $x;
?>
If 39787.0 is in the database, what value is that in a real date (using the application)? If it's 2008-12-05, the it's a VB Date. Do you know what the application was written in? I've seen people use the VB Date data type and store it in an 8 byte float in Btrieve (back in 2003). If it's a VB Date, 1 is 1899-12-31. You should be able to add the number to 1899-12-30 to get the correct date value. Something like:
<?php
$date = new DateTime('1899-12-30');
$date->add(new DateInterval('P39787D'));
echo $date->format('Y-m-d') . "\n";
?>

PHP convert 2 digit year to a 4 digit year

I have data coming from the database in a 2 digit year format 13 I am looking to convert this to 2013 I tried the following code below...
$result = '13';
$year = date("Y", strtotime($result));
But it returned 1969
How can I fix this?
$dt = DateTime::createFromFormat('y', '13');
echo $dt->format('Y'); // output: 2013
69 will result in 2069. 70 will result in 1970. If you're ok with such a rule then leave as is, otherwise, prepend your own century data according to your own rule.
One important piece of information you haven't included is: how do you think a 2-digit year should be converted to a 4-digit year?
For example, I'm guessing you believe 01/01/13 is in 2013. What about 01/01/23? Is that 2023? Or 1923? Or even 1623?
Most implementations will choose a 100-year period and assume the 2-digits refer to a year within that period.
Simplest example: year is in range 2000-2099.
// $shortyear is guaranteed to be in range 00-99
$year = 2000 + $shortyear;
What if we want a different range?
$baseyear = 1963; // range is 1963-2062
// this is, of course, years of Doctor Who!
$shortyear = 81;
$year = 100 + $baseyear + ($shortyear - $baseyear) % 100;
Try it out. This uses the modulo function (the bit with %) to calculate the offset from your base year.
$result = '13';
$year = '20'.$result;
if($year > date('Y')) {
$year = $year - 100;
}
//80 will be changed to 1980
//12 -> 2012
Use the DateTime class, especially DateTime::createFromFormat(), for this:
$result = '13';
// parsing the year as year in YY format
$dt = DateTime::createFromFormat('y', $result);
// echo it in YYYY format
echo $dt->format('Y');
The issue is with strtotime. Try the same thing with strtotime("now").
Simply prepend (add to the front) the string "20" manually:
$result = '13';
$year = "20".$result;
echo $year; //returns 2013
This might be dumbest, but a quick fix would be:
$result = '13';
$result = '1/1/20' . $result;
$year = date("Y", strtotime($result)); // Returns 2013
Or you can use something like this:
date_create_from_format('y', $result);
You can create a date object given a format with date_create_from_format()
http://www.php.net/manual/en/datetime.createfromformat.php
$year = date_create_from_format('y', $result);
echo $year->format('Y')
I'm just a newbie hack and I know this code is quite long. I stumbled across your question when I was looking for a solution to my problem. I'm entering data into an HTML form (too lazy to type the 4 digit year) and then writing to a DB and I (for reasons I won't bore you with) want to store the date in a 4 digit year format. Just the reverse of your issue.
The form returns $date (I know I shouldn't use that word but I did) as 01/01/01. I determine the current year ($yn) and compare it. No matter what year entered is if the date is this century it will become 20XX. But if it's less than 100 (this century) like 89 it will come out 1989. And it will continue to work in the future as the year changes. Always good for 100 years. Hope this helps you.
// break $date into two strings
$datebegin = substr($date, 0,6);
$dateend = substr($date, 6,2);
// get last two digits of current year
$yn=date("y");
// determine century
if ($dateend > $yn && $dateend < 100)
{
$year2=19;
}
elseif ($dateend <= $yn)
{
$year2=20;
}
// bring both strings back into one
$date = $datebegin . $year2 . $dateend;
I had similar issues importing excel (CSV) DOB fields, with antiquated n.american style date format with 2 digit year. I needed to write proper yyyy-mm-dd to the db. while not perfect, this is what I did:
//$col contains the old date stamp with 2 digit year such as 2/10/66 or 5/18/00
$yr = \DateTime::createFromFormat('m/d/y', $col)->format('Y');
if ($yr > date('Y')) $yr = $yr - 100;
$md = \DateTime::createFromFormat('m/d/y', $col)->format('m-d');
$col = $yr . "-" . $md;
//$col now contains a new date stamp, 1966-2-10, or 2000-5-18 resp.
If you are certain the year is always 20 something then the first answer works, otherwise, there is really no way to do what is being asked period. You have no idea if the year is past, current or future century.
Granted, there is not enough information in the question to determine if these dates are always <= now, but even then, you would not know if 01 was 1901 or 2001. Its just not possible.
None of us will live past 2099, so you can effectively use this piece of code for 77 years.
This will print 19-10-2022 instead of 19-10-22.
$date1 = date('d-m-20y h:i:s');

strtotime() converts a non existing date to another date

I am building a timestamp from the date, month and year values entered by users.
Suppose that the user inputs some wrong values and the date is "31-02-2012" which does not exist, then I have to get a false return. But here its converting it to another date nearby. Precisely to: "02-03-2012"..
I dont want this to happen..
$str = "31-02-2012";
echo date("d-m-Y",strtotime($str)); // Outputs 02-03-2012
Can anyone help? I dont want a timestamp to be returned if the date is not original.
You might look into checkdate.
That's because strtotime() has troubles with - since they are used to denote phrase like -1 week, etc...
Try
$str = '31-02-2012';
echo date('d-m-Y', strtotime(str_replace('-', '/', $str)));
However 31-02-2012 is not a valid English format, it should be 02-31-2012.
If you have PHP >= 5.3, you can use createFromFormat:
$str = '31-02-2012';
$d = DateTime::createFromFormat('d-m-Y', $str);
echo $d->format('d-m-Y');
You'll have to check if the date is possible before using strtotime. Strtotime will convert it to unix date meaning it will use seconds since... This means it will always be a date.
You can workaround this behavior
<?php
$str = "31-02-2012";
$unix = strtotime($str);
echo date('d-m-Y', $unix);
if (date('d-m-Y', $unix) != $str){
echo "wrong";
}
else{
echo date("d-m-Y", $unx);
}
or just use checkdate()
Use the checkdate function.
$str = "31-02-2012";
$years = explode("-", $str);
$valid_date = checkdate($years[1], $years[0], $years[2]);
Checkdate Function - PHP Manual & Explode Function - PHP Manual
Combine date_parse and checkdate to check if it's a valid time.
<?php
date_default_timezone_set('America/Chicago');
function is_valid_date($str) {
$date = date_parse($str);
return checkdate($date['month'], $date['day'], $date['year']);
}
print is_valid_date('31-02-2012') ? 'Yes' : 'No';
print "\n";
print is_valid_date('28-02-2012') ? 'Yes' : 'No';
print "\n";
Even though that date format is acceptable according to PHP date formats, it may still cause issues for date parsers because it's easy to confuse the month and day. For example, 02-03-2012, it's hard to tell if 02 is the month or the day. It's better to use the other more specific date parser examples here to first parse the date then check it with checkdate.

change dd/mm/yy date format to yy/mm/dd using php

I'm having date 20/12/2001 in this formate . i need to convert in following format 2001/12/20 using php .
$var = explode('/',$date);
$var = array_reverse($var);
$final = implode('/',$var);
Your safest bet
<?php
$input = '20/12/2001';
list($day, $month, $year) = explode('/',$input);
$output= "$year/$month/$day";
echo $output."\n";
Add validation as needed/desired. You input date isn't a known valid date format, so strToTime won't work.
Alternately, you could use mktime to create a date once you had the day, month, and year, and then use date to format it.
If you're getting the date string from somewhere else (as opposed to generating it yourself) and need to reformat it:
$date = '20/12/2001';
preg_replace('!(\d+)/(\d+)/(\d+)!', '$3/$2/$1', $date);
If you need the date for other purposes and are running PHP >= 5.3.0:
$when = DateTime::createFromFormat('d/m/Y', $date);
$when->format('Y/m/d');
// $when can be used for all sorts of things
You will need to manually parse it.
Split/explode text on "/".
Check you have three elements.
Do other basic checks that you have day in [0], month in [1] and year in [2] (that mostly means checking they're numbers and int he correct range)
Put them together again.
$today = date("Y/m/d");
I believe that should work... Someone correct me if I am wrong.
You can use sscanf in order to parse and reorder the parts of the date:
$theDate = '20/12/2001';
$newDate = join(sscanf($theDate, '%3$2s/%2$2s/%1$4s'), '/');
assert($newDate == '2001/12/20');
Or, if you are using PHP 5.3, you can use the DateTime object to do the converting:
$theDate = '20/12/2001';
$date = DateTime::createFromFormat('d/m/Y', $theDate);
$newDate = $date->format('Y/m/d');
assert($newDate == '2001/12/20');
$date = Date::CreateFromFormat('20/12/2001', 'd/m/Y');
$newdate = $date->format('Y/m/d');

Categories