As a follow-up to my last post about Javascript date functions, I went ahead and implemented strftime for javascript.
Have a look at the demo at the link above, and download the code: strftime.js. It's distributed under a BSD license, so use it and give me feedback. Post comments here for now.The code is documented using doxygen style comments.
You should also check out Stoyan's time input library that lets you do the equivalent of php's strtotime function.
Update: This code is now part of the YUI library and all further development will be done there.
/bb|[^b]{2}/
Never stop Grokking
Wednesday, April 23, 2008
Labels
2fa
4.01-strict
404
accessibility
acer
airport wifi
algorithm
android
apache
API
att
audio
australia
authentication
ayttm
badges
bandwidth
bbc
bcp
berlin
bigsur
blog
blogger
blogger template
bof
book
boomerang
broken
bug
byte order
c
caching
chrome
closure
cmc
cms
codepo8
colours
comic strip
comments
communication
compile
conference
confoo
congestion-control
cookies
correlation
couchdb
cracker
crash
creative
credit card
crockford
cron
crux
csrf
css
curl
cwv
data tags
database
date
db
delicious
design
developer
dhtml
dns
docker
dom
dopplr
dragdrop
DST
dynamic script node
education
email
emotion
endianness
entities
ephemeral ports
epicondylitis
error checking
esmtp
everybuddy
extensions
facebook
favicon
fc9
fedora
fidelity
filesystem
firefox
firesheep
flickr
flot
form
forms
fosdem
foss
foss.in
freebsd
freedom
freestyle
ftp
function currying
gdb
geek
geo
george
gmail
gnome
google
gradient
groupon
hack
hacker
hardy
hash
howtos
htc
html
html5
http
i18n
icici
ie
iit
im
innerHTML
instant messaging
interfaces
internet
internet explorer
ios
ip
ip address
ipc
iphone
ipv6
iso8601
ISP
jabber
javascript
jslint
json
julia
keynote
latency
latex
LC_TIME
lcp
linux
load
localisation
login
lsm
luhn
MAC
macosx
mail
mathematics
mathjax
measurement
media queries
meetup
memory
messaging
microformats
missing kids
mobile
montreal
movable type
mp3
mvc
mysql
name generator
navtiming
network
nexus
nodejs
notes
opensource
opera
partition
passwords
pdf
perception
performance
perl
phone
php
planet
png
ports
prerender
printing
privacy
programming
programming style
progressive enhancement
psychology
puzzle
recovery
redhat
regex
regular expressions
resource timing
review
rfc2822
rfc3339
rhel
roundtrip
rss
rum
rwd
safari
sampling
scalability
scripting
search
secnet
security
sed
segfault
self extracting tarball
sendmail
seo
server
shell
shell script
sigdashes
site
slideshare
smtp
soap
sockets
spoofing
SQL
ssl
starttls
startup
statistics
stoyan
strftime
stubbornella
sydney
sysadmin
tablespace
talks
tcp
tcp-slow-start
testing
theme
thisisbroken
thisisfixed
thoughts
throughput
tim berners-lee
timezone
tips
toc
toy
transactions
twitter
two factor auth
typing
ubuntu
ui
unicode
unix
url
usability
ux
velocity
vint cerf
w3c
wav
web
web services
webcam
webdev
webdu
webkit
webperf
webtiming
whois
widgets
wifi
windows
workaround
write performance
X
xss
yahoo
ydn
YQL
yslow
yui
Translate this page
- PHOTO FEED
- Blog feed bluesmoon@Mastodon
- © PHILIP TELLIS
The other side of the moon by Philip Tellis is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.
24 comments :
Hi,
I ran into what looks like a bug with timezone specifiers:
Value of format specifier %z is printed out as "+0-300" (should be
"+0300"), as d.getTimezoneOffset() returns a negative number, and xPad
doesn't take the minus character into account. My simple fix: replace
var H = Date.ext.util.xPad(parseInt(o/60, 10), 0);
with
var H = Date.ext.util.xPad(parseInt(Math.abs(o)/60, 10), 0);
Also, with %Z, your script relies on date string containing the name of timezone in parentheses. This holds for Firefox, but not for Internet Explorer
(tested on 7.0.5730.13), on which you get the whole date string (looks bad).
Otherwise this is a fine script, especially since localisation is so easy. Thanks!
Thanks for the report. I've fixed this in svn, and given you credit for it.
I'll make a release once I've tested this, and the %p changes I've made.
Hi,
Very nice stuff! I've been working with the PHP.JS project and your function would make a nice addition there (ours is an MIT-style license, which looks like it will fit fine with yours).
I'll need to mix it around (i.e., not use a class), since we are insisting that each function can work independently just as a function, with the exception of sometimes using, out of necessity, a global window.php_js object.
There are a few items you may be interested in:
1. There is a call to "Date.ext.util.G" which should apparently be "Date.ext.formats.G"
2. To aggregates, add the following (also add it to the regular expressions): F: '%y-%m-%d',
3. To formats, add the following (also add it to the regular expression): l: function (d) {var l=d.getHours()%12; return Date.ext.util.xPad(l===0?12:l, ' ');},
s: function(d) { return Date.parse(d)/1000; },
4. You may wish to add their documentation from PHP as well for F, l, s
5. It looks like Date.ext.formats.c is not being used
6. When you copy one object to another directly, you are copying by reference--so your assignments for the en-US, en-GB, and en-AU are all tied together. You might consider first wrapping the right-hand assignment in a call to a copy() function like this:
var _copy = function (orig) {
var newObj = {};
for (var i in orig) {
newObj[i] = orig[i];
}
return newObj;
};
7. And if you want to be a little more open to XHTML: var NS_XHTML = 'http://www.w3.org/1999/xhtml';
var NS_XML = 'http://www.w3.org/XML/1998/namespace';
if (document.getElementsByTagNameNS &&
document.getElementsByTagNameNS(NS_XHTML, 'html')[0]) {
if (document.getElementsByTagNameNS(NS_XHTML, 'html')[0].getAttributeNS &&
document.getElementsByTagNameNS(NS_XHTML, 'html')[0].getAttributeNS(NS_XML, 'lang')) {
Date.prototype.locale = document.getElementsByTagName(NS_XHTML, 'html')[0].getAttributeNS(NS_XML, 'lang');
}
else if(document.getElementsByTagNameNS(NS_XHTML, 'html')[0].lang) { // XHTML 1.0 only
Date.prototype.locale = document.getElementsByTagNameNS(NS_XHTML, 'html')[0].lang
}
}
else if(document.getElementsByTagName('html')[0] && document.getElementsByTagName('html')[0].lang) {
Date.prototype.locale = document.getElementsByTagName('html')[0].lang;
}
Look forward to your version of strptime() (hint hint) ;)
best, Brett
Hi Brett, thanks for the comments and detailed suggestions. I've actually folded this implementation into the YUI library - it's part of the datasource utility and referred to as YAHOO.util.Date. It probably already has some of the fixes that you've suggested since I went all out with completeness on that version.
YUI is under the BSD license, so should also be compatible with your project. Feel free to pull the implementation out of there and reuse it. The main difference is that the YUI version does not touch the Date prototype.
As regards strptime. Well, let's say that I've been thinking about it :)
Very cool, Blues--I noticed a couple improvements there which I also added to our version... Well, if it is any help, I see at the PHP manual page for strptime() that there is a link to some code meant to implement it in PHP (since it is not available for Windows), which might be of some help: http://sauron.lionel.free.fr/?page=php_lib_strptime . You might also see the comment about it at http://php.net/strptime
best wishes and thanks so much again!
Thanks for the link Brett, though I might have to implement sscanf in Javascript first (though I'm sure you probably already have that done).
My approach is more likely to be regex based. The bigger problem though is locale support. The parser for en-UK dates is going to be different from the parser for fr-CA dates.
No, unfortunately no sscanf yet. (We have printf and sprintf though.)
By the way, as I see Yahoo did in making a separate locale package (your work too?), I had some fun adding a setlocale() function for PHP--so some of your work should end up in that function too. It's funny how certain features like setlocale(), and even potentially the output buffering functions in PHP can be mimicked in JavaScript--while still keeping the simple PHP syntax (though we can still wrap all of the functions in a namespace and/or an instantiable/configurable class--the latter being a future goal).
Anyhow, thanks again, and it'd be great if you could drop us a note if you came up with something and don't mind.
best, Brett
yeah, DateLocale is also my work. I actually have a php script to generate javascript date locales. It's pretty simple actually. Something like this:
setlocale(LC_TIME, 'locale');
$lc = array (
"a" => array(),
"A" => array(),
"b" => array(),
"B" => array(),
"c" => "%Y %m %d (%a) %r",
"p" => array(),
"P" => array(),
"r" => "%p %I %M %S %p %Z",
"x" => "%Y %m %d",
"X" => "%H %M %S"
);
$lc['c'] = strftime("%c");
$lc['r'] = strftime("%r");
$lc['x'] = strftime("%X");
$lc['X'] = strftime("%X");
for($i=6; $i<13; $i++)
{
$d = strtotime("2008/01/$i");
$lc['a'][] = strftime("%a", $d);
$lc['A'][] = strftime("%A", $d);
}
for($i=1; $i<13; $i++)
{
$d = strtotime("2008/$i/1");
$lc['b'][] = strftime("%b", $d);
$lc['B'][] = strftime("%B", $d);
}
$d = strtotime("2008/01/01 10:00:00");
$lc['p'][] = strftime("%p", $d);
$lc['P'][] = strftime("%p", $d);
$d = strtotime("2008/01/01 22:00:00");
$lc['p'][] = strftime("%p", $d);
$lc['P'][] = strftime("%p", $d);
echo json_encode($lc);
Hello, we are working on an open source javascript libary that aims to port php functionality to javascript here: http://phpjs.org and we would very much like to use your strftime in it.
Would you be okay with it if we credit it to you? Our dual license is: mit/gpl
kvz, like I mentioned to Brett above, you'd be better off using the code from the YUI library where I've made many bug fixes and enhancements. YUI is under the BSD licence, so you should be able to copy the code as long as you maintain the licence for that one function.
Hi again Blues,
Just letting you know, I've just finished a fairly complete implementation of sscanf(): http://github.com/kvz/phpjs/blob/master/functions/strings/sscanf.js
I'm hoping to work on strptime() tomorrow and can let you know.
As it seems you may be interested in locales, I just came across
http://api.dojotoolkit.org/jsdoc/HEAD/dojo.cldr and http://bugs.dojotoolkit.org/browser/dojo/trunk/cldr/
which looks like an exciting beginning to get CLDR in JavaScript. That is what is being used in PHP6 and covers all kinds of locale stuff.
Thanks Brett, that's pretty awesome.
Ok, hopefully our new strptime() doesn't have too many bugs... :)
http://github.com/kvz/phpjs/blob/master/functions/datetime/strptime.js
>>> d = new Date(1230659252000) ==> Tue Dec 30 2008 09:47:32 GMT-0800 (PST)
>>> d.toLocaleFormat("%G-%V") ==> "2009-01"
>>> d.strftime("%G-%V") ==> "2008-54"
There is no ISO week 54, so this appears to be a bug in this implementation of strftime. I noticed that this has been moved to YUI, so I'm looking at that version instead. Thanks for your work on this project.
wow, I had no idea about toLocaleFormat and that it could take strftime formats
It's better to use something like your strftime script because .toLocaleFormat() is only supported by some browsers. The example I gave doesn't work in WebKit, and I imagine it doesn't work in IE either.
I checked YUI DataType.Date.format() and it produces the expected output.
YUI().use("datatype-date", function(Y) {
d = new Date(1230659252000);
console.log(Y.DataType.Date.format(d, {format:"%G-%V"}))
});
yeah, I have made fixes to the YUI version that I haven't had a chance to backport to my version.
I was thinking more along the lines of using toLocaleFormat if it exists and fall back to the regex parse when it doesn't. It might make things much faster on browsers that do support it.
Good library. I added a %i format item because the way %I writes values 1-9 with a
leading 0 looks incorrect to the average American eye. My patch is at http://pastie.org/2225114
(because I can't figure out how to get the comment system to accept preformatted text.
@Eric what you want should already be available as %l (that's a lower case L).
Hmm, actually it looks like I haven't ported all my changes back into this library. I've been maintaining the code as part of the YUI library, so all my fixes have been in there. See here for docs: http://developer.yahoo.com/yui/3/api/DataType.Date.html#method_format
I really appreciated your strftime demo page. Very helpful for debugging the exact combination of codes to get the desired result. For instance, I'm using wview to show my weather station, and the stationDate parameter will use strftime parameters, but most folks just accept the default %x (uses the system locale), and you're stuck with your server's preferred date format and a separate (but non-configurable) stationTime. But I discovered that I could get both the date AND TIME into the date field, configured the way *I* want, using strftime parameters (thanks to your demo): %B %e, %G %t %I:%M %P (that is, a result like: "March 6, 2016 10:12 pm").
Kudos!! and Thanks!
John, Waco, TX
I really appreciated your strftime demo page. Very helpful for debugging the exact combination of codes to get the desired result. For instance, I'm using wview to show my weather station, and the stationDate parameter will use strftime parameters, but most folks just accept the default %x (uses the system locale), and you're stuck with your server's preferred date format and a separate (but non-configurable) stationTime. But I discovered that I could get both the date AND TIME into the date field, configured the way *I* want, using strftime parameters (thanks to your demo): %B %e, %G %t %I:%M %P (that is, a result like: "March 6, 2016 10:12 pm").
Kudos!! and Thanks!
John, Waco, TX
@hamradio, thank you for your comments.
Thanks a million
Post a Comment