Use PHP functions in JavaScript

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);}
external links: original PHP docs | raw js source

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.

Comments

Add Comment
Use:
[CODE]
your_stuff('here');
[/CODE]
for proper code formatting
By submitting code here you are allowing us to use it in php.js hence dual licensing it under the MIT and GPL licenses

Gravatar
clinisbut
Aug 2nd Permalink

q  Hi, I'm having an issue with date function.
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?

Gravatar
Kevin van Zonneveld
Apr 23rd Permalink

q  @ 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

Gravatar
Rafał Kukawski
Apr 23rd Permalink

q  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.

Gravatar
Rafal Kukawski
Apr 23rd Permalink

q  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.

Gravatar
Thomas Beaucourt
19 Dec '09 Permalink

q  @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;
}

Gravatar
JT
1 Dec '09 Permalink

q  Might help if I had declared jsdate as a var in my post below, I suppose =)

JT

Gravatar
JT
1 Dec '09 Permalink

q  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

Gravatar
Theriault
30 Nov '09 Permalink

q  @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);
},

Gravatar
Thomas Beaucourt
26 Nov '09 Permalink

q  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; i return 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 !

Gravatar
Felix Blaschke
12 Nov '09 Permalink

q  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"

Gravatar
Felix Blaschke
12 Nov '09 Permalink

q  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);
            },

Gravatar
Kevin van Zonneveld
8 Nov '09 Permalink

q  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?

Gravatar
Theriault
8 Nov '09 Permalink

q  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.

Gravatar
Theriault
8 Nov '09 Permalink

q  @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);

Gravatar
Brett Zamir
7 Nov '09 Permalink

q  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?

Gravatar
Kevin van Zonneveld
7 Nov '09 Permalink

q  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

Gravatar
Theriault
30 Oct '09 Permalink

q  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.

Gravatar
Theriault
25 Oct '09 Permalink

q  't' could be shortened to:

return (new Date((f.n() + 1) + '/0/' + f.Y())).getDate();

Gravatar
Theriault
25 Oct '09 Permalink

q  'B' could be simplified to:

return pad(Math.floor(((t.getUTCHours() * 36e2) + (t.getUTCMinutes() * 60) + t.getUTCSeconds() + 36e2) / 86.4) % 1e3, 3);

Gravatar
Brett Zamir
19 Sep '09 Permalink

q  @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!

Gravatar
Alex
18 Sep '09 Permalink

q  @Brett Don't think it would matter, but my timestamp comes from JSON obtained by jQuery.

Gravatar
Alex
18 Sep '09 Permalink

q  @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.

Gravatar
Brett Zamir
18 Sep '09 Permalink

q  @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?

Gravatar
Alex
18 Sep '09 Permalink

q  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.

Gravatar
Alex
18 Sep '09 Permalink

q  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);

Gravatar
Brett Zamir
18 Sep '09 Permalink

q  @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?

Gravatar
Alex
18 Sep '09 Permalink

q  Having the same issue as Paul

date('Y-m-d',data.ts)



is returning NaN-NaN-NaN

Gravatar
Kevin van Zonneveld
16 Aug '09 Permalink

q  @ majak: Great stuff! Thanks so much. I've fixed it in SVN

Gravatar
majak
12 Aug '09 Permalink

q  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.

Gravatar
majak
12 Aug '09 Permalink

q  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.

Gravatar
Kevin van Zonneveld
24 Jul '09 Permalink

q  @ Paul: I wasn't able to reproduce that. Are you using the latest version? Which browser/interpreter are you testing this in?

Gravatar
Paul
21 Jul '09 Permalink

q  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

Gravatar
Kevin van Zonneveld
13 Jan '09 Permalink

q  @ 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!

Gravatar
David Randall
10 Jan '09 Permalink

q  Rather than strictly adhering to the PHP version for the 2nd argument, I suggest checking for the Javascript Date() object. Consider the following:

[CODE=&quot;Javascript&quot;]
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=&quot;Javascript&quot;]
var a, jsdate=((timestamp) ? new Date(timestamp*1000) : new Date());
[/CODE]

to

[CODE=&quot;Javascript&quot;]
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]

Gravatar
Kevin van Zonneveld
7 Jan '09 Permalink

q  @ Brett Zamir: Excellent Work Brett, amazing that we have the date function almost complete! Thx

Gravatar
Brett Zamir
7 Jan '09 Permalink

q  Sorry, meant to post my last comment over at PHP JS Namespaced instead...

Gravatar
Brett Zamir
7 Jan '09 Permalink

q  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=&quot;Javascript&quot;]
// 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 &lt; arr.length; i++) {
this[arguments[i]] = arr[i];
}
}
alert(drink +' is '+color+' and '+power +' makes it special.\n'); // Example from PHP manual
[/CODE]

Gravatar
Brett Zamir
7 Jan '09 Permalink

q  Here's 'o' with some tests confirming it works (I tested the others too)
[CODE=&quot;Javascript&quot;]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=&quot;Javascript&quot;]o: function(){
if (f.n() === 12 &amp;&amp; f.W() === 1) {
return jsdate.getFullYear()+1;
}
if (f.n() === 1 &amp;&amp; f.W() &gt;= 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.

Gravatar
Brett Zamir
7 Jan '09 Permalink

q  Here's one more...

Thanks for the idea to check the source code. It gave this one away...

[CODE=&quot;Javascript&quot;]r: function(){
return f.D()+', '+f.d()+' '+f.M()+' '+f.Y()+' '+f.H()+':'+f.i()+':'+f.s()+' '+f.O();
},[/CODE]

Gravatar
Brett Zamir
7 Jan '09 Permalink

q  Two small additions:

[CODE=&quot;Javascript&quot;]
u: function(){
return pad(jsdate.getMilliseconds()*1000, 6);
},
[/CODE]
[CODE=&quot;Javascript&quot;]
Z: function(){
var t = -jsdate.getTimezoneOffset()*60;
return t;
},
[/CODE]

Note also that your chart should change the description of 'u' from &quot;milliseconds&quot; to &quot;microseconds&quot; per the current PHP documentation for date().

Gravatar
Kevin van Zonneveld
6 Jan '09 Permalink

q  @ Bryan Elliott: Thanks a lot Bryan!

Gravatar
Bryan Elliott
6 Jan '09 Permalink

q  Implementation of I:
[CODE=&quot;Javascript&quot;]
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]

Gravatar
Kevin van Zonneveld
22 May '08 Permalink

q  @ Bob: Thanks. Maybe you could use js' native getTimezoneOffset()/60 ?

Gravatar
Bob
21 May '08 Permalink

q  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?

Gravatar
Kevin van Zonneveld
11 Apr '08 Permalink

q  @ Tim Wiel: Thanks alot for sharing your improvement Tim!

Gravatar
Tim Wiel
11 Apr '08 Permalink

q  Calling [CODE=&quot;javascript&quot;]$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=&quot;Javascript&quot;]jsdate = new Date(timestamp ? timestamp * 1000 : null);[/CODE]

to read

[CODE=&quot;Javascript&quot;]jsdate=((timestamp) ? new Date(timestamp*1000) : new Date())[/CODE]

Gravatar
Michael White
6 Mar '08 Permalink

q  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. :)

Gravatar
Kevin van Zonneveld
5 Mar '08 Permalink

q  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 :)

Gravatar
Michael White
5 Mar '08 Permalink

q  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 &amp;&amp; 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 &quot;home&quot;. If you &quot;travel&quot; 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 &quot;0&quot; 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.

Gravatar
Kevin van Zonneveld
5 Mar '08 Permalink

q  @ Michael White: Google FTW indeed :) Still curious why we're experiencing the difference then though.


Contribute a New function

More functions

In this category

checkdate
» date
date_default_timezone_get
date_default_timezone_set
date_parse
getdate
gettimeofday
gmdate
gmmktime
gmstrftime
idate
localtime
microtime
mktime
strftime
strptime
strtotime
time
timezone_abbreviations_list
timezone_identifiers_list

Support us

spread the word:


Use any PHP function in JavaScript


These kind folks have already donated: @HalfWinter, Paulo Freitas, Andros Peña Romo, Nitin Gupta, @nikosdion, Anonymous, Anonymous and Shawn Houser.
<your name here>

Click here to lend your support to: phpjs and make a donation at www.pledgie.com !