Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Copyright (c) 2012, Markus Ivan Peloquin <markus@cs.wisc.edu>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS' AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
- // TODO test the week logic more
- /*
- * Usage:
- *
- * var d = new Date(0);
- * var format = '%F %T %Z';
- *
- * // module interface
- * Strftime.strftime(format, d); // 1969-12-31 16:00:00 UTC-8
- * Strftime.strftime_utc(format, d); // 1970-01-01 00:00:00 UTC
- *
- * // OO interface
- * d.strftime(format); // 1969-12-31 16:00:00 UTC-8
- * d.strftime_utc(format); // 1970-01-01 00:00:00 UTC
- *
- * The language must be overriden by adding the strings to Strftime.langs.XX
- * and setting Strftime.lang = 'XX'. The locale must be overriden by adding
- * the strings to Strftime.locales.YY and setting Strftime.locale = 'YY'.
- */
- Strftime = (function(){ // begin Strftime namespace
- var Strftime = {
- langs: {},
- locales: {},
- };
- function pad2z(x)
- {
- return (x<10 ? '0' : '') + x;
- }
- function pad2w(x)
- {
- return (x<10 ? ' ' : '') + x;
- }
- function pad3z(x)
- {
- return (x<100 ? (x<10 ? '00' : '0') : '') + x;
- }
- function weekday(lang, x, abbrev)
- {
- return lang.weekdays[abbrev?1:0][x];
- }
- function month(lang, x, abbrev)
- {
- return lang.months[abbrev?1:0][x];
- }
- function short_hour(x)
- {
- return !x ? 12 : x>12 ? x-12 : x;
- }
- // recursion could be used, but...
- function insert(fmt, chars)
- {
- var chars0 = fmt.split('');
- chars0.reverse();
- chars.push.apply(chars, chars0);
- }
- // weeknum(real day-of-year, day-of-year of first day of week 1)
- function weeknum(days, day0)
- {
- days -= day0;
- return days<0 ? 52 : (days/7 |0) + 1;
- }
- // it's much easier to compute these all at once rather than piecemeal;
- // people usually want both cweek and cwyear anyway
- function make_week_stats(date)
- {
- var start = new Date(date.getTime());
- start.setMonth(0);
- start.setDate(1);
- start.setHours(0);
- start.setMinutes(0);
- start.setSeconds(0);
- start.setMilliseconds(0);
- var days = (date.getTime() - start.getTime()) /
- (1000 * 60 * 60 * 24) |0;
- var start_weekday = start.getDay();
- // day0_sun = -sw mod 7, 0<=day0_sun<7
- var day0_sun = (start_weekday<1 ? 0 : 7) - start_weekday;
- // day0_mon = 1-sw mod 7, 0<=day0_mon<7
- var day0_mon = (start_weekday<2 ? 1 : 8) - start_weekday;
- // day0_cw = 1-sw mod 7, -2<=day0_cw <4
- var day0_cw = (start_weekday<4 ? 1 : 8) - start_weekday;
- var cweek = weeknum(days, day0_cw);
- var cwyear = date.getFullYear() + (
- days<7 && cweek==52 ? -1 :
- days>300 && cweek==1 ? 1 : 0);
- return {
- days: days,
- week_sun: weeknum(days, day0_sun),
- week_mon: weeknum(days, day0_mon),
- cweek: cweek,
- cwyear: cwyear,
- };
- }
- function strftime(fmt, date)
- {
- var chars = fmt.split('');
- chars.reverse();
- var lang = Strftime.langs[Strftime.lang];
- var locale = Strftime.locales[Strftime.locale];
- var res = '';
- var week_stats = null;
- var c;
- var code;
- // temporary variables
- var days;
- var h;
- var minutes;
- var sign;
- while ((c = chars.pop()) != null) {
- if (c != '%') {
- res += c;
- continue;
- }
- if ((c = chars.pop()) == null)
- throw new Error('Format cannot end with `%\'');
- code = c.charCodeAt(0);
- switch (c) {
- case 'g': case 'G':
- case 'j':
- case 'U': case 'V': case 'W':
- week_stats = week_stats || make_week_stats(date);
- }
- switch (c) {
- // weekday name
- case 'a': case 'A':
- // abbreviate if 'a'
- res += weekday(lang, date.getDay(), code==0x61);
- break;
- // month name
- case 'b': case 'B':
- case 'h':
- // abbreviate if not 'B'
- res += month(lang, date.getMonth(), code!=0x42);
- break;
- // locale
- case 'c': // datetime
- case 'X': // time
- case 'x': // date
- insert(locale[code==0x63 ? 'datetime' :
- code==0x78 ? 'date' : 'time'], chars);
- break;
- // century
- case 'C':
- res += pad2z(date.getFullYear() / 100 |0);
- break;
- // date
- case 'd':
- case 'e':
- // pad with zeros for 'd'
- res += (code==0x64 ? pad2z : pad2w)(date.getDate());
- break;
- // MM/DD/YY
- case 'D':
- insert('%m/%d/%y', chars);
- break;
- // YYYY-MM-DD
- case 'F':
- insert('%Y-%m-%d', chars);
- break;
- // ISO8601 year
- case 'g':
- res += pad2z(week_stats.cwyear % 100);
- break;
- // ISO8601 year
- case 'G':
- res += week_stats.cwyear;
- break;
- // hour
- case 'H': // zero-padded
- case 'k': // white-padded
- res += (code==0x48 ? pad2z : pad2w)(date.getHours());
- break;
- // short hour
- case 'I': // zero-padded
- case 'l': // white-padded
- res += (code==0x49 ? pad2z : pad2w)(short_hour(
- date.getHours()));
- break;
- // day-of-year
- case 'j':
- res += pad3z(week_stats.days);
- break;
- // month
- case 'm':
- res += pad2z(date.getMonth()+1);
- break;
- // minutes
- case 'M':
- res += pad2z(date.getMinutes());
- break;
- // newline
- case 'n':
- res += '\n';
- break;
- // am/pm
- case 'p':
- case 'P':
- res += lang.ampm[date.getHours()>11 ?
- (code==0x50 ? 3 : 1) : // pm : PM
- (code==0x50 ? 2 : 0)]; // am : AM
- break;
- // H:MM:SS AMPM
- // e.g. ' 9:00:00 PM'
- case 'r':
- insert('%I:%M:%S %p', chars);
- break;
- // HH:MM
- case 'R':
- insert('%H:%M', chars);
- break;
- // seconds
- case 'S':
- res += pad2z(date.getSeconds());
- break;
- // tab
- case 't':
- res += '\t';
- break;
- // HH:MM:SS
- case 'T':
- insert('%H:%M:%S', chars);
- break;
- // day of week, 1-7, monday=1
- case 'u':
- res += date.getDay()+1;
- break;
- // week num, start sun, 1 has first sun
- case 'U':
- res += pad2z(week_stats.week_sun);
- break;
- // week num, start mon, 1 has jan 4
- case 'V':
- res += pad2z(week_stats.cweek);
- break;
- // day of week, 0-6, monday=1
- case 'w':
- res += date.getDay();
- break;
- // week num, start mon, 1 has first mon
- case 'W':
- res += pad2z(week_stats.week_mon);
- break;
- // not technically correct, but...
- case 'E':
- case 'O':
- insert(locale.datetime, chars);
- break;
- // year w/o century
- case 'y':
- res += pad2z(date.getYear() % 100);
- break;
- // full year
- case 'Y':
- res += date.getFullYear();
- break;
- // utc offset -hhmm +hhmm
- case 'z':
- minutes = date._is_utc ? 0 : date.getTimezoneOffset();
- res += minutes<0 ? '+' : '-';
- minutes = Math.abs(minutes);
- res += pad2z(minutes / 60 |0) + pad2z(minutes % 60);
- break;
- // tz name (lazy implementation)
- case 'Z':
- minutes = date._is_utc ? 0 : date.getTimezoneOffset();
- sign = minutes<0 ? '+' : '-';
- minutes = Math.abs(minutes);
- if (minutes % 60)
- insert('%z', chars);
- else if (!minutes)
- res += 'UTC';
- else
- res += 'UTC' + sign + (minutes / 60 |0);
- break;
- case '%':
- res += '%';
- break;
- default:
- throw new Error('Unrecognized format %' + c);
- }
- }
- return res;
- }
- function utc(date)
- {
- date = new Date(date.getTime() + date.getTimezoneOffset() * 60000);
- date._is_utc = true;
- return date;
- }
- function strftime_utc(fmt, date)
- {
- return strftime(fmt, utc(date));
- }
- Strftime.strftime = strftime;
- Strftime.strftime_utc = strftime_utc;
- Date.prototype.strftime = function(fmt) { return strftime(fmt, this) };
- Date.prototype.strftime_utc = function(fmt) { return strftime_utc(fmt, this) };
- return Strftime;
- })(); // end Strftime namespace
- Strftime.langs.en = {
- weekdays: [
- 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday'.split(' '),
- 'Sun Mon Tue Wed Thurs Fri Sat'.split(' ')
- ],
- months: [
- 'January February March April May June July August September October November December'.split(' '),
- 'Jan Feb Mar Apr May June July Aug Sep Oct Nov Dec'.split(' ')
- ],
- ampm: ['AM', 'PM', 'am', 'pm']
- };
- Strftime.langs.de = {
- weekdays: [
- 'Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag'.split(' '),
- 'So Mo Di Mi Do Fr Sa'.split(' ')
- ],
- months: [
- 'Januar Februar M\0xe4rz April Mai Juni Juli August September Oktober November Dezember'.split(' '),
- 'Jan Feb Maart Apr Mei Juni Juli Aug Sept Okt Nov Dec'.split(' ')
- ],
- ampm: ['AM', 'PM', 'am', 'pm']
- };
- // the Unix 'C' locale
- Strftime.locales.C = {
- datetime: '%Y-%m-%d %H:%M:%S',
- date: '%Y-%m-%d',
- time: '%H:%M:%S'
- };
- Strftime.locales.DE = Strftime.locales.C;
- Strftime.locales.US = {
- datetime: '%m/%d/%y %H:%M:%S',
- date: '%m/%d/%y',
- time: '%H:%M:%S',
- };
- Strftime.locales.UK = {
- // ick
- datetime: '%d/%m/%y %H:%M:%S',
- date: '%d/%m/%y',
- time: '%H:%M:%S',
- };
- // setting the default language/locale
- Strftime.lang = 'en';
- Strftime.locale = 'C';
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement