JavaScript readable date/time from PHP's time() - php

Is it possible to have JavaScript compute a timestamp returned from PHP's time() function and present it in a readable format such as "Sun, 18th April 2010 at 4:00 pm"?

Use the Date object to do that:
new Date(<?php echo time(); ?>*1000)
You need to multiply the Unix timestamp by 1000 becuase Date expects the timestamp to be in milliseconds.
And to format the date, you can use this Date.format method (Date has none built in).

You're going to want to be really careful doing this stuff. When you take a server-side time value that's a traditional "number of seconds (or milliseconds) since the Epoch boundary" value, and then turn that into some sort of "Date" object, well a translation occurs into the time zone appropriate to the locale of the context.
The problem arises when you've got a server located in Chicago, and somebody in Hawaii using your site, say after a party — one of those "luau" affairs, no doubt, complete with roasted pig and grass-skirted dancing girls, a rare evening under warm tropical skies, exotic flowers scenting the ocean breezes — and it's late now. My goodness, it's almost midnight! Whatever will mother think when I write her about the party?
Our party-goer sits down at 11:30 PM to use your site. Now, of course, being considerably east of Hawaii, your server thinks it's 5:30AM, and the date is one day later than the date our party-goer will jot down in his quick note to Mom. So your server writes its time value into a web page as described in the answers here, and — correctly — the local Hawaii time shows up on the page in our party-goer's hotel room.
The problem is this: if that local time makes it back to your application from some form field, and your application treats it as local time in Chicago, then your site will get yesterday's date. Depending on your application that's either OK or it's not OK - the point is, you have to keep track of where a date (expressed in ordinary calendar notation) comes from vis-a-vis where the date is used.
You can of course have the opposite problem. That is, if your server always renders dates in its local time zone, then users elsewhere in the world will see confusing (apparently wrong) date and time values, so the interface has to make clear what those values mean. The issues become important when your site provides services involving schedules. If it's possible to schedule operations, it's important that the interface keeps things on the level so that "April 30th at 10:00PM" means either that date and time at the server or that date and time in the locale from which the schedule was arranged. Whichever it is, you have to be careful to keep things consistent.

Instead of a numeric unix timestamp you can also send a textual representation of the date that Date.parse() understands.
Maybe it's just my contribution to global warming but I think there are benefits in using a format that is a bit more human readable and contains the timezone info.
e.g.
<?php
// I have "decided" America/Los_Angeles fits most of my audience
date_default_timezone_set('America/Los_Angeles');
$now = time();
$yesterday = strtotime('yesterday', $now);
// March 27, 1976 08:00:00 tz:America/Los_Angeles
$someotherdate = mktime(8, 0, 0, 3, 27, 1976)
?><html>
<head><title>...</title>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
function foo() {
$('.datetime').each( function() {
var t = $(this).text();
t = new Date(Date.parse(t)).toLocaleString();
$(this).text(t);
});
}
</script>
</head>
<body>
<div><span class="datetime"><?php echo date(DateTime::RSS, $now); ?></span></div>
<div><span class="datetime"><?php echo date(DateTime::RSS, $yesterday); ?></span></div>
<div><span class="datetime"><?php echo date(DateTime::RSS, $someotherdate); ?></span></div>
<button onclick="foo()">to local time</button>
</body>
</html>
This prints
Sat, 17 Apr 2010 04:40:15 -0700
Fri, 16 Apr 2010 00:00:00 -0700
Sat, 27 Mar 1976 08:00:00 -0800
in my browser and (since my local timezone is Europe/Berlin, CET, UTC+1/2) after hitting the to local time button
Samstag, 17. April 2010 13:40:15
Freitag, 16. April 2010 09:00:00
Samstag, 27. März 1976 17:00:00

It's now 2013, and as more and more people switch from processing SQL results on PHP side to passing results in JSON and processing on client side, I think moment.js deserves some attention of its own for offering easy replacements to PHP's strtotime() and date() functions in Javascript, plus some more.
Just include:
<script src="SCRIPT_DIR/moment.min.js" type="text/javascript"></script>
Then it's as easy as:
// Simulates ajax response
var data = { someDate: "2023-08-23 11:52:39" }
// .unix() converts to Unix timestamp: 1692816759
moment(data.someDate).unix();
// Displaying it in a readable format
// Aug 23, 11:52 AM
moment("2023-08-23 11:52:39").format('MMM D, hh:mm A');
// Now
moment();
// Support for manipulation and chaining
moment().add('days', 7).subtract('months', 1).hours(15).minutes(0).seconds(0);
You can get the 5.5kb js file here:
http://momentjs.com/
More docs here:
http://momentjs.com/docs/

Related

Using strtotime() PHP and revert back trough gmdate() is not returning same date

I have a string $StartDate = "2015-09-23" (should be like yyyy-mm-dd).
Than I make $UdtStart= strtotime($StartDate) that returns 1442980800;
Well if I go to this link it return back "Wed, 23 Sep 2015 04:00:00 +0000".
First, why do we have 04:00:00 added?
Than, if I do this $back=gmdate("Y-m-d H:i:s", ($UdtStart)); I will have "2015-09-26 04:00:00".
What am I missing?
$UdtStart= strtotime($StartDate);
$back=gmdate("Y-m-d H:i:s", ($UdtStart));
Wed, 23 Sep 2015 04:00:00 +0000
Note that +0000 on the end, that means the time is UTC. As per the PHP strtotime() doco:
Each parameter of this function uses the default time zone unless a time zone is specified in that parameter.
The gmdate is for Greenwich Mean Time (and really should be called something like utcdate nowadays), so you're asking for the data in a different foramt from what you gave it.
I'd be willing to bet money that you're in a timezone four hours removed from UTC, which is why you're seeing that.
If you want local time, use date() rather than gmdate(). The gmdate doco states:
Identical to the date() function except that the time returned is Greenwich Mean Time (GMT).

PHP Date / GMT Weirdness

Either I'm losing my mind, or I've not got the faintest idea what I'm doing. I'm leaning towards the latter.
I'm trying to convert this: 1316826000, which I'm pretty confident should be Sat, 24 Sep 2011 01:00:00 GMT
http://www.onlineconversion.com/unix_time.htm confirms this.
http://www.unixtimestamp.com/index.php tells me 09 / 23 / 11 # 8:00:00pm EST, so far so good. I happen to be in EST, this is the result I'd like to get back from PHP.
When I do date('l, M d, Y, h:ia', $iTime), I get: Friday, Sep 23, 2011, 12:00am, a full 20 hours off.
I've confirmed the server's time is correct using date('c'). date('c') output is: 2012-05-19T03:19:20+00:00. The server is in the central time zone, where it is currently 10:20pm. May 18.
echo date_default_timezone_get() outputs "GMT" (set somewhere else in the script using date_default_timezone_set('GMT'))
What am I missing? Nothing I've read so far can explain how I'm getting a result 20 hours behind what it should be. Were it an hour fast or slow, I could at least wrap my head around it being some sort of DST idiotry, but 20? Crazyness! Thanks for reading!
Check what your php.ini says for date.timezone.
In unix it is usually here: /etc/php.ini
Then use a proper timezone recognized by PHP:
http://www.php.net/manual/en/timezones.php
date.timezone = 'America/New_York'
Then reload your web server.
Unix time just means the number of seconds since epoch. Has nothing to do with timezones. Timezones simply add or subtract 1 hour (3600 seconds) from the unix time for each zone you move away from GMT.
An example:
$userTimezone = new DateTimeZone('America/New_York');
$gmtTimezone = new DateTimeZone('GMT');
$myDateTime = new DateTime('2014-01-22 11:44', $gmtTimezone);
$offset = $userTimezone->getOffset($myDateTime);
echo $offset;
That will output: -14400 or 4 hours. Which is the difference between New York and GMT
Using some Java code with the Joda-Time 2.3 library, as I don't know PHP…
long m = 1316826000L;
DateTime dateTimeUtc = new DateTime( m * 1000L, DateTimeZone.UTC );
DateTime dateTimeNewYork = dateTimeUtc.toDateTime( DateTimeZone.forID( "America/New_York" ) );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeNewYork: " + dateTimeNewYork );
I can tell you that 1316826000 seconds from the beginning of 1970 UTC/GMT (Unix Epoch) is…
dateTimeUtc: 2011-09-24T01:00:00.000Z
dateTimeNewYork: 2011-09-23T21:00:00.000-04:00
So, as the commenter stated, it would be 8 PM in EST but EST was not in effect on that day. DST (Daylight Saving Time) (idiocy, as you correctly noted) was in effect until November 9 of that year (2011). So the time of day is pushed forward one hour, to 9 PM.
In GMT/UTC, that means 1 AM in the morning of the next day.
Standard time in east coast US is 5 hours behind UTC/GMT. With DST it is 4 hours behind UTC/GMT (one hour closer).
Where you got confused:
Your time format/conversion in incorrect.I can't help with that as I don't know PHP.
You should be using a competent date-time library for this kind of work.Date-time work is complicated, tricky, confusing, and error-prone.This question discusses possibilities of Joda-Time (for Java) sorts of libraries for PHP.
You used three-letter time zone codes. Avoid these.Those codes are neither standardized nor unique -- there are common duplicates. Instead, use proper time zone names. In your case of east coast US, "America/New_York". Furthermore, in this case you confused the time zone area and rules (east coast US) with a particular application of those rules (EST). Saying "America/New_York" means "whatever time zone rules were in effect on that date, whereas saying "EST" (if interpreted to mean Eastern Standard Time in US) means "UTC-05:00". So either (a) use a time zone name such as "America/New_York", or (b) use a specific offset such as "-05:00".

strtotime returns current year when input is in the format of YYYY and the value is greater then 1999

I'm not sure that this is a bug since after searching I can't find any duplicate experiences- however, this one has me stumped.
While in the midst of a (rather painful) script that is intended to take a bunch of freetext records and convert them to useful date records, my trusty friend strtotime() seems to have let me down.
For testing purposes, I boiled the code down to this:
<?=date('Y', strtotime("1999"));?>
Output shows: 1999
<?=date('Y', strtotime("1981"));?>
Output shows: 1981
<?=date('Y', strtotime("2001"));?>
Output shows: 2012
<?=date('Y', strtotime("2021"));?>
Output shows: 2012
Everything seems fine until the input exceeds "1999"- From that point on, every year before and after the current one returns the current year (2012)
Any input is much appreciated.
As per PHP's date/time format docs:
The "Year (and just the year)" format only works if a time string has already been found -- otherwise this format is recognised as HH MM.
(2nd last note on the page).
Try prefixing the years with Jan 1,.
For example:
<?=date('Y', strtotime("Jan 1, 2021"));?> outputs 2021 as expected.
I'm supposing this is because certain years can be incorrectly parsed as month/day pairs, such as "2012" being interpreted as "December 20th of the current year".
If you want proof for yourself, try changing the date format to r:
<?=date('r', strtotime('2001'));?> gives Thu, 23 Feb 2012 20:01:00
The problem is, that it is parsed as time, what you can see if you use date('c') instead of date('Y');.
php > var_dump(date('c', strtotime("2001")));
string(25) "2012-02-23T20:01:00+01:00"
You should pass the value unambiguous for example 2012-01-01.
Another solution is to use a function, that allows to specify the format of the given input, like strptime(), or DateTime::createFromFormat()
php > echo DateTime::createFromFormat('Y', '2001')->format('c');
2001-02-23T22:29:56+01:00
Use this:
echo date('Y', strtotime("1/1/2001"));
echo date('Y', strtotime("1/1/2021"));
Using 4 digits as date can be interpreted as time, you should use a more specific format to make sure the function works as you expect it.
So 2021 is 20:21 (24h format) of 2012
$plaintext = '2004'; //'2004-11','2004-5','2004-5-1','2004/5-1','2004/08/10'
echo date('Y', strtotime(
(strlen($plaintext)==10?$plaintext:
(strlen($plaintext)==7? str_replace('-','/',$plaintext).'/01':
(strlen($plaintext)==4?$plaintext.'/01/01':$plaintext)
)
)));

Using strtotime and taking timezone into consideration

I have a system running in PHP and am using CodeIgniter (if there is a CI specific answer to this I would be happy as well).
I often need to figure out the timestamp of dates such as "this Thursday" or "this Monday". I currently use strtotime("this Thursday") and it gives me what I ask for.
I have a server in EST. It is 01:00 (1:00am), early morning Friday, Feb 24, 2012 in New York.
I have a user who has specified his timezone to be Pacific time. Right now it is 22:00 (10pm) late evening Thursday Feb 23, 2012 in San Francisco.
I use strtotime("this Thursday"). Since my server is in EST, it returns me the timestamp for March 1, 2012. I would like to take the user's timezone into consideration. For my user, "this Thursday" should return Feb 23, 2012.
Can I use strtotime("this Thursday") for it, and if so, how would I specify the target timezone?
If not, what approach would you suggest to getting the date for "this Thursday" in a specific timezone.
The manual for strtotime links directly to date_default_timezone_set. I would take that as a hint to use that.
I just figured out that strtotime takes a $now parameter. I can specify the $now param to be the current time in the user's timezone and strtotime returns me what I need.
This is taken string from the php site
<?php
date_default_timezone_set('Asia/Shanghai');
$first_day_of_month = date('Y-m',time()) . '-01 00:00:01';
$t = strtotime($first_day_of_month);
print_r(array(
date('Y-m',$t),
date('Y-m',strtotime('- 1 month',$t)),
date('Y-m',strtotime('- 2 month',$t)),
));
?>

PHP date issues with daylight saving

I've got a very strange bug cropping up in some PHP code I've got. The page is managing student enrolments in courses. On the page is a table of the student's courses, and each row has a number of dates: when they enrolled, when they completed, when they passed the assessment and when they picked up their certificate.
The table data is generated by PHP (drawing the data from the DB), and Javascript actually renders the table. The output from PHP is JS code which looks something like this:
var e = new Enrolment();
e.contactId = 5801;
e.enrolId = 14834;
e.courseId = 3;
e.dateEnrolled = new Date(1219672800000);
e.dateCompleted = new Date(-1000); // magic value meaning they haven't completed.
e.resultDate = new Date(1223647200000);
e.certDate = new Date(1223560800000);
e.result = 95;
e.passed = true;
enrolments[14834] = e;
In the database, all the date fields are stored as DATE (not DATETIME) fields.
The bug is that the dates are being displayed as one day off. I would suspect that this has a lot to do with the server being in an area which has daylight saving, whereas here there isn't any (meaning the server time is one hour off). This explains a lot, especially how the data preparation and rendering is being done in two different timezones. That is: the server is saying to the client that the person completed at midnight on the 15th August, and the client is interpreting that as 11pm on the 14th and therefore displaying 14th August.
But here's the confusing part: it's only doing that for the resultDate and certDate fields! I've copied the data to my local server and have found that the production server is actually sending a different timestamp (one which is off by 1 hour) just for those two fields, whereas the dateEnrolled field is the same.
Here's the output using the exact same code and data from the database:
// local server (timezone GMT+1000)
e.dateEnrolled = new Date(1219672800000); // 26 Aug 2008 00:00 +10:00
e.dateCompleted = new Date(-1000);
e.resultDate = new Date(1223647200000); // 11 Oct 2008 00:00 +10:00
e.certDate = new Date(1223560800000); // 10 Oct 2008 00:00 +10:00
// production server (timezone GMT+1100)
e.dateEnrolled = new Date(1219672800000); // 26 Aug 2008 00:00 +10:00
e.dateCompleted = new Date(-1000);
e.resultDate = new Date(1223643600000); // 10 Oct 2008 23:00 +10:00 **
e.certDate = new Date(1223557200000); // 09 Oct 2008 23:00 +10:00 **
I can understand if this was a problem with Daylight Saving not being accounted for, but notice how the dateEnrolled is the same?
The PHP code which converts the MySQL date to a unix timestamp is this:
list ($year, $month, $day) = explode ('-', $mysqlDT);
$timestamp = mktime (0,0,0, $month, $day, $year);
Any ideas about how to fix this?
Thats because you use mktime which is locale specific. That is it will convert it to the number of seconds from 00:00:00 1970-1-1 GMT, and that is offset by 1 hour with one timezone.
You should also remember that the javascript does use the same timezone as the browser, not the web page.
e.resultDate = new Date(year, month - 1, day);
This will make sure the date is the same for every viewer from every timezone.
Or you can use gmmktime and use the UTC methods in Date.
Ok, I just figured out why it's mucking up one date but not the other. Daylight savings wasn't in effect in August. facepalm
always store dates/datetimes in GMT/UTC
take a good look at the query that retrieves these values, anything different about the ones being adjusted?
if not, are they all timestamp or date or datetime?
It is mosly likely to be day light saving issue.
The reason why it doing it only for resultDate and certDate is that dateEnrolled is in August, daylight saving normally begins/ends in late September or early October.
Set the date.timezone ini setting to your app's timezone, using apache.conf, .htaccess or ini_set().

Categories