JavaScript date
Format a local date/time
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 2526 27 28 29 3031 32 33 34 3536 37 38 39 4041 42 43 44 4546 47 48 49 5051 52 53 54 5556 57 58 59 6061 62 63 64 6566 67 68 69 7071 72 73 74 7576 77 78 79 8081 82 83 84 8586 87 88 89 9091 92 93 94 9596 97 98 99 100101 102 103 104 105106 107 108 109 110111 112 113 114 115116 117 118 119 120121 122 123 124 125126 127 128 129 130131 132 133 134 135136 137 138 139 140141 142 143 144 145146 147 148 149 150151 152 153 154 155156 157 158 159 160161 162 163 164 165166 167 168 169 170171 172 173 174 175176 177 178 179 180181 182 183 184 185186 187 188 189 190191 192 193 194 195196 197 198 199 200201 202 203 204 205206 207 208 209 210211 212 213 214 215216 217 218 219 220221 222 223 224 225226 227 228 229 230231 232 233 234 235236 237 238 239 240241 242 243 244 245246 247 248 249 250251 252 253 254 255256 257 258 259 260261 262 263 264 265266 267 268 269 270271 272 273 274 275276 | function date(format, timestamp) { // Format a local date/time // // version: 1008.1718 // discuss at: http://phpjs.org/functions/date // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com) // + parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html) // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + improved by: MeEtc (http://yass.meetcweb.com) // + improved by: Brad Touesnard // + improved by: Tim Wiel // + improved by: Bryan Elliott // + improved by: Brett Zamir (http://brett-zamir.me) // + improved by: David Randall // + input by: Brett Zamir (http://brett-zamir.me) // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + improved by: Brett Zamir (http://brett-zamir.me) // + improved by: Brett Zamir (http://brett-zamir.me) // + improved by: Theriault // + derived from: gettimeofday // + input by: majak // + bugfixed by: majak // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + input by: Alex // + bugfixed by: Brett Zamir (http://brett-zamir.me) // + improved by: Theriault // + improved by: Brett Zamir (http://brett-zamir.me) // + improved by: Theriault // + improved by: Thomas Beaucourt (http://www.webapp.fr) // + improved by: JT // + improved by: Theriault // + improved by: Rafał Kukawski (http://blog.kukawski.pl) // % note 1: Uses global: php_js to store the default timezone // * example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400); // * returns 1: '09:09:40 m is month' // * example 2: date('F j, Y, g:i a', 1062462400); // * returns 2: 'September 2, 2003, 2:26 am' // * example 3: date('Y W o', 1062462400); // * returns 3: '2003 36 2003' // * example 4: x = date('Y m d', (new Date()).getTime()/1000); // * example 4: (x+'').length == 10 // 2009 01 09 // * returns 4: true // * example 5: date('W', 1104534000); // * returns 5: '53' // * example 6: date('B t', 1104534000); // * returns 6: '999 31' // * example 7: date('W U', 1293750000.82); // 2010-12-31 // * returns 7: '52 1293750000' // * example 8: date('W', 1293836400); // 2011-01-01 // * returns 8: '52' // * example 9: date('W Y-m-d', 1293974054); // 2011-01-02 // * returns 9: '52 2011-01-02' var that = this, jsdate, f, formatChr = /\\?([a-z])/gi, formatChrCb, // Keep this here (works, but for code commented-out // below for file size reasons) //, tal= [], _pad = function (n, c) { if ((n = n + "").length < c) { return new Array((++c) - n.length).join("0") + n; } else { return n; } }, txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], txt_ordin = { 1: "st", 2: "nd", 3: "rd", 21: "st", 22: "nd", 23: "rd", 31: "st" }; formatChrCb = function (t, s) { return f[t] ? f[t]() : s; }; f = { // Day d: function () { // Day of month w/leading 0; 01..31 return _pad(f.j(), 2); }, D: function () { // Shorthand day name; Mon...Sun return f.l().slice(0, 3); }, j: function () { // Day of month; 1..31 return jsdate.getDate(); }, l: function () { // Full day name; Monday...Sunday return txt_words[f.w()] + 'day'; }, N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun] return f.w() || 7; }, S: function () { // Ordinal suffix for day of month; st, nd, rd, th return txt_ordin[f.j()] || 'th'; }, w: function () { // Day of week; 0[Sun]..6[Sat] return jsdate.getDay(); }, z: function () { // Day of year; 0..365 var a = new Date(f.Y(), f.n() - 1, f.j()), b = new Date(f.Y(), 0, 1); return Math.round((a - b) / 864e5) + 1; }, // Week W: function () { // ISO-8601 week number var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3), b = new Date(a.getFullYear(), 0, 4); return 1 + Math.round((a - b) / 864e5 / 7); }, // Month F: function () { // Full month name; January...December return txt_words[6 + f.n()]; }, m: function () { // Month w/leading 0; 01...12 return _pad(f.n(), 2); }, M: function () { // Shorthand month name; Jan...Dec return f.F().slice(0, 3); }, n: function () { // Month; 1...12 return jsdate.getMonth() + 1; }, t: function () { // Days in month; 28...31 return (new Date(f.Y(), f.n(), 0)).getDate(); }, // Year L: function () { // Is leap year?; 0 or 1 var y = f.Y(), a = y & 3, b = y % 4e2, c = y % 1e2; return 0 + (!a && (c || !b)); }, o: function () { // ISO-8601 year var n = f.n(), W = f.W(), Y = f.Y(); return Y + (n === 12 && W < 9 ? -1 : n === 1 && W > 9); }, Y: function () { // Full year; e.g. 1980...2010 return jsdate.getFullYear(); }, y: function () { // Last two digits of year; 00...99 return (f.Y() + "").slice(-2); }, // Time a: function () { // am or pm return jsdate.getHours() > 11 ? "pm" : "am"; }, A: function () { // AM or PM return f.a().toUpperCase(); }, B: function () { // Swatch Internet time; 000..999 var H = jsdate.getUTCHours() * 36e2, // Hours i = jsdate.getUTCMinutes() * 60, // Minutes s = jsdate.getUTCSeconds(); // Seconds return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3); }, g: function () { // 12-Hours; 1..12 return f.G() % 12 || 12; }, G: function () { // 24-Hours; 0..23 return jsdate.getHours(); }, h: function () { // 12-Hours w/leading 0; 01..12 return _pad(f.g(), 2); }, H: function () { // 24-Hours w/leading 0; 00..23 return _pad(f.G(), 2); }, i: function () { // Minutes w/leading 0; 00..59 return _pad(jsdate.getMinutes(), 2); }, s: function () { // Seconds w/leading 0; 00..59 return _pad(jsdate.getSeconds(), 2); }, u: function () { // Microseconds; 000000-999000 return _pad(jsdate.getMilliseconds() * 1000, 6); }, // Timezone e: function () { // Timezone identifier; e.g. Atlantic/Azores, ...// The following works, but requires inclusion of the very large // timezone_abbreviations_list() function. /* var abbr = '', i = 0, os = 0; if (that.php_js && that.php_js.default_timezone) { return that.php_js.default_timezone; } if (!tal.length) { tal = that.timezone_abbreviations_list(); } for (abbr in tal) { for (i = 0; i < tal[abbr].length; i++) { os = -jsdate.getTimezoneOffset() * 60; if (tal[abbr][i].offset === os) { return tal[abbr][i].timezone_id; } } } */ return 'UTC'; }, I: function () { // DST observed?; 0 or 1 // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC. // If they are not equal, then DST is observed. var a = new Date(f.Y(), 0), // Jan 1 c = Date.UTC(f.Y(), 0), // Jan 1 UTC b = new Date(f.Y(), 6), // Jul 1 d = Date.UTC(f.Y(), 6); // Jul 1 UTC return 0 + ((a - c) !== (b - d)); }, O: function () { // Difference to GMT in hour format; e.g. +0200 var a = jsdate.getTimezoneOffset(); return (a > 0 ? "-" : "+") + _pad(Math.abs(a / 60 * 100), 4); }, P: function () { // Difference to GMT w/colon; e.g. +02:00 var O = f.O(); return (O.substr(0, 3) + ":" + O.substr(3, 2)); }, T: function () { // Timezone abbreviation; e.g. EST, MDT, ... // The following works, but requires inclusion of the very // large timezone_abbreviations_list() function./* var abbr = '', i = 0, os = 0, default = 0; if (!tal.length) { tal = that.timezone_abbreviations_list(); } if (that.php_js && that.php_js.default_timezone) { default = that.php_js.default_timezone; for (abbr in tal) { for (i=0; i < tal[abbr].length; i++) { if (tal[abbr][i].timezone_id === default) { return abbr.toUpperCase(); } } } } for (abbr in tal) { for (i = 0; i < tal[abbr].length; i++) { os = -jsdate.getTimezoneOffset() * 60; if (tal[abbr][i].offset === os) { return abbr.toUpperCase(); } } } */ return 'UTC'; }, Z: function () { // Timezone offset in seconds (-43200...50400) return -jsdate.getTimezoneOffset() * 60; }, // Full Date/Time c: function () { // ISO-8601 date. return 'Y-m-d\\Th:i:sP'.replace(formatChr, formatChrCb); }, r: function () { // RFC 2822 return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb); }, U: function () { // Seconds since UNIX epoch return jsdate.getTime() / 1000 | 0; } }; this.date = function (format, timestamp) { that = this; jsdate = ( (typeof timestamp === 'undefined') ? new Date() : // Not provided (timestamp instanceof Date) ? new Date(timestamp) : // JS Date() new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int) ); return format.replace(formatChr, formatChrCb); }; return this.date(format, timestamp);} |
Examples
» Example 1
Running
1 | date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400); |
Should return
1 | '09:09:40 m is month' |
» Example 2
Running
1 | date('F j, Y, g:i a', 1062462400); |
Should return
1 | 'September 2, 2003, 2:26 am' |
Dependencies
No dependencies, you can use this function standalone.
Open syntax issues
php.js uses JsLint to help us keep our code consistent and prevent some common bugs.
Eventually we want all code to pass or at least take into consideration most fixes suggested by JsLint, following this JsLint configuration we’ve decided on.
Authors
Thanks to the following developers, you get to have date goodness in JavaScript.
@ Rafał Kukawski: I think I agree. As long as it's 10:00:00 (.9), it still is 10:00:00 and not 10:00:01 implemented your fix, thanks a lot! http://github.com/kvz/phpjs/commit/c3cd2f82d214c4b11edac89d14162fcad3a5675e
IMO in U() we should do Math.floor instead of Math.round, cause we shouldn't add 1 sec to the result when the millisecond part is just over 500. If you agree, my proposition is
U: function () { // Seconds since UNIX epoch
return Math.floor(jsdate.getTime() / 1000);
}
or even
U: function () { // Seconds since UNIX epoch
return jsdate.getTime() / 1000 | 0;
}
U: function () { // Seconds since UNIX epoch
return jsdate / 1e3 | 0;
}
if you accept less self-explaining code.
My proposition for checking for leap years would be
L: function(){
return new Date(jsdate.getFullYear(), 1, 29).getMonth()==1|0;
}
It uses the JS engine to calculate the correct month for February 29 for given year.
@Theriault :
Current timezone is Paris GMT+1 (winter / DST off)
Your variant works, provided you throw in a +1 :
z: function (){
return Math.round((new Date(f.Y(), f.n() - 1, f.j()) - new Date(f.Y(), 0, 1)) / 864e5) + 1;
}
Great work on an incredibly useful function, guys.
Seems like repeatedly declaring the regEx and all of those inner functions every time the date function is called would be pretty inefficient, though. Have you considered doing something like this?
var date = (function () {
function pad(n, c) {
...
}
var that = this,
formatChr = /\\?([a-z])/gi,
txt_words = [ ... ],
txt_ordin = { ... },
f = {
w : function (d) {
return d.getDay();
},
...
};
return function (format, timestamp) {
// Just for clarity :$
if (timestamp) {
jsdate = (timestamp instanceof Date) ? new Date(timestamp) : new Date(timestamp * 1000);
} else {
jsdate = new Date();
}
return format.replace(formatChr, function (t, s) {
return f[t] ? f[t](jsdate) : s;
});
};
}());
JT
@Felix: The 'W' function has been updated with a new algorithm. Thank you for your contribution.
@Thomas: I cannot seem to reproduce the bug you are experiencing. What is your system's current timezone offset and what browser are you using? Also, does the following code also fix the problem:
z: function () {
return Math.round((new Date(f.Y(), f.n() - 1, f.j()) - new Date(f.Y(), 0, 1)) / 864e5);
},
The "z" function is buggy.
It doesn't account for daylight saving time when doing :
(jsdate - new Date(jsdate.getFullYear() + "/1/1")) / 864e5
thus it returned 2 days more for '2009-10-25' than for '2009-10-24'.
My fixed function is :
z: function (){
var m = f.n();
var z = 0;
for (i=1; ireturn z + f.j();
}
Which uses an improved t function accepting a parameter :
t: function (n) {
if (n == undefined) n = jsdate.getMonth() + 1;
if ( n == 2 ) return 28 + f.L();
if ( n & 1 && n < 8 || !(n & 1) && n > 7 ) return 31;
return 30;
}
Thanks for the good work !
Sorry for repost: I mean 2nd january 2006 returns wrong week number.
php.date("W", new Date(2006,0,2)) // correct result would be "1"
The "W" function is wrong. For example for the 2nd january 2005 it returns the wrong weak number. I correct it myself with another algorithm:
// Week
W: function () {
var x = (new Date(jsdate.getFullYear(), 0, 4))
var a = new Date(jsdate.getFullYear(), 0, 4-(x.getDay()==0 ? 7:x.getDay()-1))
for (var w=0; w <= 53; w++) {
var b = new Date(a.getFullYear(), a.getMonth(), a.getDate()+(w-1)*7, 0,0,0,0)
var c = new Date(a.getFullYear(), a.getMonth(), a.getDate()+w*7, 0,0,0,0)
if (jsdate >= b && jsdate < c) {break;}
}
if (w >= 1 && w <= 52) {return w;}
if (w >= 52 && w != ((new Date(jsdate.getFullYear(),0,1)).getDay() == 4 ? 53 : 52)) {return 1;}
return ((new Date(jsdate.getFullYear(),0,1)).getDay() == 4 ? 53 : 52);
},
Hey there Theriault!
Blown away by your expertise & quality of code. Let me try to reach you by mail and see if you'd like to append the code another way ; )
If you haven't received my mail drop another line here, ok?
The return function at the bottom could be shortened to one line using a ternary operator:
return format.replace(/\\?([a-z])/gi, function (t, s) {return f[t] ? f[t]() : s;});
"I" could not rely on the _dst function up top and be shortened to one line:
return 0 + (t.getTimezoneOffset() < Math.max((new Date(d.Y(), 0, 1)).getTimezoneOffset(), (new Date(d.Y(), 6, 1)).getTimezoneOffset()));
And a bunch of little nitpicky fixes that I can suggest:
txt_weekdays at the top could remove the repeat of 'day' 7 times and just add 'day' to the 'l' (lowercase-L) function:
var txt_weekdays = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur"]; return txt_weekdays[f.w()] + 'day';
'N' could be like 'g' and use the OR operator to make it a little shorter:
return f.w() || 7;
'S' could also use the OR operator to make it a bit shorter:
return txt_ordin[f.j()] || 'th';
'o' (lowercase O) could be shortened to one line:
return f.Y() + (f.n() == 12 && f.W() < 9 ? -1 : (f.n() == 1 && f.W() > 9 ? 1 : 0));
'M' could be one line:
return f.F().slice(0, 3);
'D' could be one line:
return f.l().slice(0, 3);
Thanks. Keep up the good work PHP.JS.
@Brett: I was unsure, but after reviewing ECMA-262, it is a part of the ECMA standards. The standards state that date arguments are to be treated as finite integers and they all support values outside the ranges (such as 13, 1000, or even -500 for the month). The date argument formula is:
Day(Result(7)) + Result(4) − 1.
Day(Result(7)) returns the computed days since Jan 1, 1970 for the current time's year and month, Result(7), plus Result(4) which is the integer date argument, so 0 would add no days to the first of the calculated month and year, then it subtracts one day to account for the first day of the month which was included in the calculation of Result(7), so that would be the previous month's last day.
I would have to say that the algorithm's that ECMA has laid out for date handling are the best I've seen out there; very flexible. To think that Date.setDate(Date.getDate() - 7) subtracts one week exactly, or Date.setMonth(Date.getMonth() - 6) can subtract half a year is fantastic, no matter the date.
However, the way I did it is incorrect. A string argument being passed to the Date constructor may be handled differently by all browsers. 't' should be changed to use 3 integers in the constructor instead:
return (new Date(f.Y(), f.n() + 1, 0).getDate();
I believe I have found the solution to 'W', also. The following should work after reviewing ISO-8601 algorithms for calculating the week. I have confirmed it works from Jan 1 1900 to Dec 32 2100, which is likely enough testing:
return 1 + Math.round(((c = new Date(d.Y(), d.n() - 1, d.j() - d.N() + 3)) - (new Date(c.getFullYear(), 0, 4))) / 864e5 / 7);
Does anyone know whether the technique of setting a date to '0' to get the last day of the month (as used in Theriault's 't' implementation) part of the ECMAScript spec or is it just a browser convention?
Hey Theriault, thanks for your improvements. I've just added them to the repo.
http://github.com/kvz/phpjs/commit/0a830484289ece0cebdbf6d2fafe849b9308284b
As for the W: issue, I've added a testcase (#8) that confirms we stray from PHP's behavior there () (but it seems PHP in turn strays from my System's calendar ; ), this will require a quiet sunday afternoon of tesing & fixing though..
If anyone is up for a challenge, that would rock! :D
I found a bug with 'W'. For 2010, week 52 runs from 12/27/2010 to 12/31/2010 (only 5 days), then 1/1/2011 is week 53, then 1/2/2011 to 1/3/2011 are the last two days of week 52. Then week 1 is 1/4/2011 to 1/9/2011 (only 6 days). It seems to happen on other dates, too, with some weeks having only 6 days and some having 8 days.
'B' could be simplified to:
return pad(Math.floor(((t.getUTCHours() * 36e2) + (t.getUTCMinutes() * 60) + t.getUTCSeconds() + 36e2) / 86.4) % 1e3, 3);
@Alex: The issue should be fixed now. Our date functions were only accepting "undefined" (or missing) timestamps, numeric timestamps, or JavaScript Date() object timestamps. If they were expressed as a string or other non-object types, there was no attempt to auto-convert them (as PHP does). It seems therefore that your JSON was returning timestamps as strings and not numbers, thus causing a mismatch. However, the latest version in git can handle the strings now too: http://github.com/kvz/phpjs/commits/master/functions/datetime/date.js/8a428dccc64253a59b84b692fbfe323f5e9d29c9 . FYI, you might want to check out https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Operators/Special_Operators#conditional_operator to understand what the code at the beginning of the function is doing when assigning timestamp to a Date object, if you were not clear. Have fun!
@Brett It was a standard unix timestamp in seconds. (meant to indicate that in my inital post). It appears that the original source code handled a conversion (line 39 in v909.322).
I imagine that was written this way in the first place to handle PHP defaulting to mktime() if the 2nd argument isn't set, but I don't see anywhere where that actually happens, thus if the typeof(timestamp) fails there is no value when the JS Date() methods are called.
@Alex: Thanks. Now, what data did you have in "data.ts" and what type (Number, Date object?). And though I don't think it would matter in this case, are you using a Unix timestamp as in seconds (as in PHP), or a JavaScript value in milliseconds?
I should mention that I first encountered this issue in Chrome 3, and tested my fix in Chrome 3, FF 3.5, IE8, Safari 3.2.2, and Opera 9.64 all on Windows XP.
I altered the code from the above code (marked as version 909.322 (had the same issue in code marked 2.91)) by deleting lines 37-41 and inserting at line 37:
var jsdate = new Date(); jsdate.setTime(timestamp * 1000);
@Alex: As Kevin asked Paul, are you using the latest version? What browser? Have you tried placing alerts within the date() function to see at least where things go wrong?
I found another bug. Format character 'N' doesn't work according to the specification.
It is easy to fix. Just replace "return f.w() + 1;" on line 92
with "return f.w() ? f.w() : 7;" or something in that manner.
This line:
$P.date('W', $P.strtotime('2005-01-01'));
returns 0 instead of 53.
(Verified in PHP. Problem is in function date, not strtotime.)
I used the latest minified and namespaced version.
@ Paul: I wasn't able to reproduce that. Are you using the latest version? Which browser/interpreter are you testing this in?
I try this function and it doesn't work like the php's function, at least in my test.
[CODE]
date('d/m/Y', 1247788516)
[CODE]
it return: NaN/NaN/NaN
and php's function return: 16/07/2009
Regards
@ David Randall: I had no issues running your 3rd example in our testsuite. Maybe it's browser-specific? I've added your code anyway, because it doesn't hurt any other testcase, and I agree that your 3rd example should work. Thanks for contributing!
Rather than strictly adhering to the PHP version for the 2nd argument, I suggest checking for the Javascript Date() object. Consider the following:
[CODE="Javascript"]
date('Y m d'); // 2009 01 09
date('Y m d', time()); // 2009 01 09
date('Y m d', new Date()); // 40996 08 16
date('Y m d', (new Date()).getTime()/1000); // 2009 01 09
(new Date()).getTime()/1000; // 1231560959.38
time(); // 1231560959
[/CODE]
The third line doesn’t produce the correct value because date() is expecting an integer as the 2nd argument. To make this easier for Javascript dates, I suggest changing the following
[CODE="Javascript"]
var a, jsdate=((timestamp) ? new Date(timestamp*1000) : new Date());
[/CODE]
to
[CODE="Javascript"]
var a, jsdate=(
(typeof(timestamp) == 'undefined') ? new Date() : // Not provided
(typeof(timestamp) == 'number') ? new Date(timestamp*1000) : // UNIX timestamp
new Date(timestamp) // Javascript Date()
);
[/CODE]
Despite my comment just now about not porting list(), if you can make a small exception for working around the desire to copy PHP behavior perfectly, the following will work if the last argument is the array to be assigned to list() instead of as an assignment (list is a language construct and not a function anyways):
[CODE="Javascript"]
// Only works in global context
list('drink', 'color', 'power', ['coffee', 'brown', 'caffeine']);
function list () {
var arr = arguments[arguments.length-1]
for (var i=0; i < arr.length; i++) {
this[arguments[i]] = arr[i];
}
}
alert(drink +' is '+color+' and '+power +' makes it special.\n'); // Example from PHP manual
[/CODE]
Here's 'o' with some tests confirming it works (I tested the others too)
[CODE="Javascript"]alert(date('Y W o', Date.UTC(2008,11,28)/1000)) // normal
alert(date('Y W o', Date.UTC(2008,11,29)/1000))
alert(date('Y W o', Date.UTC(2011,0, 3)/1000))
alert(date('Y W o', Date.UTC(2010,0, 3)/1000))
alert(date('Y W o', Date.UTC(2010,0, 4)/1000)) // normal
[/CODE]
[CODE="Javascript"]o: function(){
if (f.n() === 12 && f.W() === 1) {
return jsdate.getFullYear()+1;
}
if (f.n() === 1 && f.W() >= 52) {
return jsdate.getFullYear()-1;
}
return jsdate.getFullYear();
},[/CODE]
Now, it looks like we only have the timezone identifiers, 'e' and 'T' left to do.
Here's one more...
Thanks for the idea to check the source code. It gave this one away...
[CODE="Javascript"]r: function(){
return f.D()+', '+f.d()+' '+f.M()+' '+f.Y()+' '+f.H()+':'+f.i()+':'+f.s()+' '+f.O();
},[/CODE]
Two small additions:
[CODE="Javascript"]
u: function(){
return pad(jsdate.getMilliseconds()*1000, 6);
},
[/CODE]
[CODE="Javascript"]
Z: function(){
var t = -jsdate.getTimezoneOffset()*60;
return t;
},
[/CODE]
Note also that your chart should change the description of 'u' from "milliseconds" to "microseconds" per the current PHP documentation for date().
Implementation of I:
[CODE="Javascript"]
I: function(){
var
DST = (new Date(jsdate.getFullYear(),6,1,0,0,0)),
DST = DST.getHours()-DST.getUTCHours(),
ref = jsdate.getHours()-jsdate.getUTCHours();
return ref!=DST?1:0;
},
[/CODE]
Very interesting project. I came across your date function while looking for an easy way to detect a user's local timezone abbreviation. But your timezone options don't appear to work yet. Is that a known issue? Any other suggestions?
Calling [CODE="javascript"]$PHP_JS.date(); [/CODE] doesn't return todays date in Mozilla Firefox 2.0.13 on Ubuntu Linux
To fix it I changed the line reading
[CODE="Javascript"]jsdate = new Date(timestamp ? timestamp * 1000 : null);[/CODE]
to read
[CODE="Javascript"]jsdate=((timestamp) ? new Date(timestamp*1000) : new Date())[/CODE]
Haha, that's ok. I can't pretend that it isn't confusing. I guessed correctly the first time way back at the beginning of this saga but it took me a little while and a bit of research into the subject before I really was able to wrap my head around it. :)
Yeah it does. That's actually what I meant before but the UTC being a 'Universal Time' got me all confused again ;) Time problems tend to do that to me :)
According the epoch definition it makes complete sense that our time zones would affect the output of what appears to be the same date. Explanation below.
For our purposes: UTC = GMT && GMT = UTC // They never differ by more than 0.9 seconds
If the epoch was set in UTC time then UTC +1 = CET (your time zone). That means that 00000 seconds in UTC time is equal to 03600 seconds in CET time.
That also means that 00000 seconds in UTC time is equal to -18000 seconds in EST (my time zone).
The final result is that any given point in UNIX epoch time is exactly 21600 seconds different between our time zones (6 hours) which will yield a different date for the same epoch second depending on your time zone.
Layman's terms: UNIX epoch uses UTC zone as "home". If you "travel" outside that zone then you have to take that difference into account. When it was midnight January 1st, 1970 in the UTC zone it was still December 31st here in my time zone. Therefore the "0" second of the UNIX epoch will represent the date Dec. 31, 1969 for EST and will read correctly for you since it was already Jan. 1st 1970 in CET when the unix epoch was set.
I think that out of those explanations you should find one that makes sense to you.


clinisbut
Aug 2nd
Starting from a timestamp, I'm adding seven days and converting to string using date() function. Rarely, when I add seven days to 2010-10-31 it gives me 2010-11-6 instead of 2010-11-7.
This is my code
$P = new PHP_JS(); timestamp = $P.mktime( 0, 0, 0,month, day, year ); temp = timestamp + (60*60*24*7); string_date = $P.date('d-m-Y', temp));Other dates work fine... is this a bug?