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
Tuesday, April 22, 2008
Javascript date functions
I keep forgetting what I can do with dates in javascript, so this post is just a list of built in date functions. I've also seen a lot of sites that do some terrible things with javascript dates including trying to parse it out of a string, or using getYear(). Don't do that.
I've also seen sites that contain arrays of calendar month names and days of the week. This is locale specific, so do it only if you're willing to make the array easily localised.
To create a new date object:
Also don't forget the
After this line,
One useful method is
A useful page for javascript date functions is quackit.com
I mentioned earlier that you should not use
I'd always thought about writing an equivalent to
Update: I've built an implementation of strftime in javascript. This implementation is also part of the YUI library.
I've also seen sites that contain arrays of calendar month names and days of the week. This is locale specific, so do it only if you're willing to make the array easily localised.
To create a new date object:
var d = new Date; var d = new Date('2008/04/22'); var d = new Date('2008/04/22 01:03:31'); var d = new Date(1208758100000);Note: don't type that into firefox/firebug while editing a post on blogger - they have a global variable called
d
which is used to save your post.Also don't forget the
new
keyword. Without that you'll just create a string containing the current date.After this line,
d
evaluates to a string representation of the date which isn't very useful for anything since it's almost always not what you want. You really want to get various parts of the date out. There's a whole bunch of functions to do that:d.getYear(); // deprecated function to get year. don't use this d.getFullYear(); // get four digit year. use this d.getMonth(); // get the month 0 - 11 d.getDate(); // get the day of the month 1 - 31 d.getDay(); // get the day of the week 0-6 (Sunday is 0) d.getHours(); // get the hour - 0-23. Note the s in the function name d.getMinutes(); // get the minutes of the hour - 0-59 d.getSeconds(); // get the seconds of the minute - 0-59 d.getMilliseconds(); // get milliseconds past the second - 0-999 d.getTime(); // get number of milliseconds since the epoch. integer divide by 1000 to get unix timestamp d.getTimezoneOffset(); // get offset from GMT in minutes - note capitalisationAll of these functions return the value for your current timezone. To get values in UTC, add
UTC
after the get
in the method name. There are also equivalent set
methods, but I've never needed to use them.One useful method is
parse()
which takes in a string representation of a date and returns the number of milliseconds since the epoch for that. You can call this directly on the Date class.A useful page for javascript date functions is quackit.com
I mentioned earlier that you should not use
getYear();
. This is so because this method is not quite Y2K compliant. It is sort of compliant, but browsers don't implement it in the same way. The standard says that it should return the number of years since 1900, which means 2000 would be 100 and 2008 would be 108. Netscape/Firefox does that correctly (possibly because they defined the standard back in the day), but IE decided to 'fix' it by returning 4 digit years for anything past 1999, which means that 1999 is 99 while 2000 is 2000. Your code gets unwieldy trying to manage it, so it's best to just use getFullYear().I'd always thought about writing an equivalent to
strftime
for javascript, but never got down to it. In my mind, it would be something that uses a regex with a callback function, and I'd use the unique property of javascript that allows one to call an object's methods like keys in an associative array. Basically something like this:var fmt = {'Y': 'getFullYear', 'm': 'getMonth', 'd': 'getDate'}; Date.prototype.strftime = function(str) { var d = this; var ret = str.replace(/%([Ymd])/g, function(m0, m1) { return d[fmt[m1]](); }); d=null; return ret; };I'll have to build on that sometime.
Update: I've built an implementation of strftime in javascript. This implementation is also part of the YUI library.
Tuesday, April 01, 2008
Gmail SMTP with sendmail
I was speaking with my dad on Skype yesterday when he told me that his mails weren't getting sent out, they were all stuck in his mail queue. Now before we go on, it's important to understand the outgoing mail set up.
My dad's machine has fetchmail fetching mail from various POP3 servers and sorting them into each user's mail spool, and it has sendmail to send mail using gmail's SMTP servers. This is perfectly okay, since my dad uses gmail.
Now if you go through gmail's configuration documentation, they say that you need SMTP over SSL on port 587 with TLS. They also say to use smtp.googlemail.com, but we'll ignore that, because we're not in the UK.
Setting this up requires a few simple steps.
Unfortunately, all doesn't go well. Mails don't go out, and in /var/log/maillog, you get errors saying "smtp.gmail.com: No route to host". You can try a traceroute and a ping, and they'll both succeed.
The problem is with that port 587 thing. For whatever reason, sendmail keeps trying port 25 even though 587 is the specified mail submit port, and sometime in the last few days or weeks, gmail stopped accepting mail submits on port 25 (at least that's what it looks like).
So, get back to your config file. This time I didn't know what options to use, but I know more or less what the sendmail.cf syntax means, and how to edit that file, so I edited it directly.
I went down to the line that starts with
Restart sendmail, and all works.
But this isn't a good solution, because the next time you regenerate sendmail.cf from sendmail.mc, your change will be overwritten.
So, what I did next, was go into /usr/share/sendmail-cf and run
My dad's machine has fetchmail fetching mail from various POP3 servers and sorting them into each user's mail spool, and it has sendmail to send mail using gmail's SMTP servers. This is perfectly okay, since my dad uses gmail.
Now if you go through gmail's configuration documentation, they say that you need SMTP over SSL on port 587 with TLS. They also say to use smtp.googlemail.com, but we'll ignore that, because we're not in the UK.
Setting this up requires a few simple steps.
- First, create your sendmail certificate:
cd /usr/share/ssl/certs
Note that you can run
make sendmail.pemmake usage
in this directory for help. Also this directory is created by the openssl package, so make sure you have that. - Next, define the SMART_HOST as esmtp:smtp.gmail.com and add certificate paths:
define(`SMART_HOST', `esmtp:smtp.gmail.com')dnl
define(`CERT_DIR', `/usr/share/ssl/certs')
define(`confCACERT_PATH', `CERT_DIR')
define(`confCACERT', `CERT_DIR/ca-bundle.crt')
define(`confCRL', `CERT_DIR/sendmail.pem')
define(`confSERVER_CERT', `CERT_DIR/sendmail.pem')
define(`confSERVER_KEY', `CERT_DIR/sendmail.pem')
define(`confCLIENT_CERT', `CERT_DIR/sendmail.pem')
define(`confCLIENT_KEY', `CERT_DIR/sendmail.pem') - Now add PLAIN and LOGIN to confAUTH_MECHANISMS so that it looks like this:
define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 PLAIN LOGIN')dnl
This requires the Cyrus SASL library, which you probably already have - You also need to create an auth-info file that looks something like this:
youraddress@gmail.com
Make sure this file is only readable by root.
youraddress@gmail.com
yourgmailpassword
smtp.gmail.com - Now regenerate everything and start sendmail. On RedHat based systems, this is as easy as running
/etc/init.d/sendmail restart
. On other systems you may have to runmake
first (or you may not have to use sendmail at all :)
Unfortunately, all doesn't go well. Mails don't go out, and in /var/log/maillog, you get errors saying "smtp.gmail.com: No route to host". You can try a traceroute and a ping, and they'll both succeed.
The problem is with that port 587 thing. For whatever reason, sendmail keeps trying port 25 even though 587 is the specified mail submit port, and sometime in the last few days or weeks, gmail stopped accepting mail submits on port 25 (at least that's what it looks like).
So, get back to your config file. This time I didn't know what options to use, but I know more or less what the sendmail.cf syntax means, and how to edit that file, so I edited it directly.
I went down to the line that starts with
Mesmtp
, and looked for the line below that which said TCP $h
, which basically means connect using TCP to the host specified in $h. We need to add the port to this line. Change the line to TCP $h 587
and we're done.Restart sendmail, and all works.
But this isn't a good solution, because the next time you regenerate sendmail.cf from sendmail.mc, your change will be overwritten.
So, what I did next, was go into /usr/share/sendmail-cf and run
grep -r '^Mesmtp' *
. The result which stood out was the mailer file. Inside that file, I saw that the TCP $h
line was being added by the macro ESMTP_MAILER_ARGS, so, I just needed to add this one line after the SMART_HOST:define(`ESMTP_MAILER_ARGS', `TCP $h 587')dnland we're done. Restart sendmail, and the config changes are permanent. All works, and mails go out.
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.