Sugar | Javascript, sweetened.

Creating Manipulating Comparing Formatting Ranges Locales UTC Timezones

Dates

Try entering a date above. Here are some suggestions:

Creating Dates

The Date.create method is an alternate syntax to new Date() and understands a wide variety of formats. Any Sugar method that accepts dates also understands these different formats. Aside from the text formats above, timestamps as numbers are also understood, as are other date objects, which return themselves. The method can also accept enumerated params, as with new Date().  Full list of supported formats.

Also available are Date.past and Date.future. These alternate constructors are identical to Date.create except that they will prefer past or future dates when an ambiguity exists.

Finally, the Date package maps methods to the number class that will allow date creation from a number.


Date.create('January 10, 2012');
Date.create('May 1987');
Date.create('tomorrow');
Date.create(1234567899999);
Date.create(new Date());
Date.create(2011, 5, 17, 10, 30);
Date.past('Tuesday');
Date.future('Sunday');
(5).daysBefore('Monday');
(8).hoursAfter('5:45pm');

Methods that will understand these formats include the following:

Class
Method
Example
Date create
Date.create('today')
Date past
Date.past('Sunday')
Date future
Date.future('Sunday')
Date is
date1.is('Jan 25, 1990')
Date isBefore
date2.isBefore('next week tuesday')
Date isAfter
date3.isAfter('March 1st')
Date isBetween
date4.isBetween('January 11th', 'April 22nd')
Date unitSince
date5.daysSince('2008-05-25')
Date unitUntil
date6.daysUntil('2008-05-25')
Number unitBefore
num.daysBefore('2008-05-25')
Number unitAfter
num.daysAfter('2008-05-25')

Manipulating Dates

Method
Description
set Sets any unit on the date. Accepts a hash, timestamp, or enumerated params. If the second parameter is true it will also reset units that are more specific than those passed.
advance Advances the date into the future. Accepts a hash, timestamp, or enumerated params. All values are relative to the date. Also accepts a "reset" parameter like set.
rewind Rewinds the date into the past. Accepts a hash, timestamp, or enumerated params. All values are relative to the date.
addUnit Adds a unit of time to the date.
beginningOfUnit Sets the date to the beginning of that unit. Can be Day/Month/Week/Year.
endOfUnit Sets the date to the end of that unit. Can be Day/Month/Week/Year.
reset Resets all specific units on the date up to the one passed. Default is "hours", effectively resetting the time.
utc Sets a flag on the date to use UTC-based methods internally. This will not actually manipulate the date.
Date.create().set({ day: 17 });
Date.create().set({ month: 2, day: 17 });
Date.create().set({ month: 2, day: 17 }, true);
Date.create().advance({ years: 2 });
Date.create().rewind({ months: 5 });
Date.create().addYears(5);
Date.create().addDays(3);
Date.create().addHours(-11);
Date.create().beginningOfDay();
Date.create().beginningOfWeek();
Date.create().endOfMonth();
Date.create().endOfYear();
Date.create().reset();
Date.create().reset('date');
Date.create().utc(true).reset('hours').getHours();

Comparing Dates

Method
Description
is Compares the date to any format passed in. If a date object or timestamp is passed in, the date is tested to the millisecond. If a text format is used, is performs some magic that will use a precision implied in the format used. For example, if '2010' is passed, it will return true for any date between the first and last millisecond of 2010. The second parameter will add a margin of error (in milliseconds).
isAfter Will return true if the date is after the one passed.
isBefore Will return true if the date is before the one passed.
isBetween Will return true if the date is between the two passed.
isFuture Will return true if the date is in the future.
isPast Will return true if the date is in the past.
isYesterday Will return true if the date is yesterday.
isToday Will return true if the date is today.
isTomorrow Will return true if the date is tomorrow.
isWeekday Will return true if the date is Monday - Friday.
isWeekend Will return true if the date is a Saturday or Sunday.
isLastUnit Will return true if the date is last Week/Month/Year.
isThisUnit Will return true if the date is this Week/Month/Year.
isNextUnit Will return true if the date is next Week/Month/Year.
isValid Will return true if the date is valid.
isLeapYear Will return true if the date falls on a leap year.
isUTC Will return true if the date has a zero timezone offset.
Date.create().is('today');
Date.create().is('July');
Date.create().is('2011');
Date.create().isBefore('August');
Date.create().isAfter('April');
Date.create().isBetween('January', 'September');
Date.create('next week').isFuture();
Date.create('next week').isPast();
Date.create('12 hours ago').isYesterday();
Date.create('12 hours from now').isTomorrow();
Date.create().isWeekday();
Date.create().isWeekend();
Date.create('the beginning of the month').isLastWeek();
Date.create('March').isThisMonth();
Date.create('2012').isNextYear();
Date.create('beebop').isValid();
Date.create('this year').isLeapYear();

Formatting Dates

Once you have the date you want, getting it out to the proper format can be a hassle. The format method is designed to help here allowing intuitive tokens to be passed in, with some useful shortcuts. If no format is passed, Sugar will use a common format for the current locale (more on locales below). Tokens that are can be used in a formatting string are:

Token
Meaning
{ms} {milliseconds} {f} {ff} {fff} Millseconds. The {f} style format can pad up to 3 places.
{s} {ss} {seconds} Seconds. {ss} will pad to 2 places.
{m} {mm} {minutes} Minutes. {mm} will pad to 2 places.
{h} {hh} {hours} {12hr} Hours (12 hour). {hh} will pad to 2 places.
{H} {HH} {24hr} Hours (24 hour). {HH} will pad to 2 places.
{d} {dd} {date} Date. {dd} will pad to 2 places.
{dow} {weekday} Day of the week. {dow} is a 3 character abbreviation. If the first letter of any of these tokens is capitalized, the resulting string will also be capitalized.
{ord} The date with an English ordinal suffix (ex. "5th", "3rd", etc)
{M} {MM} Numeric month. {MM}, will pad to 2 places.
{mon} {month} Text month. {mon} is a 3 character abbreviation. If the first letter of any of these tokens is capitalized, the resulting string will also be capitalized.
{yy} {yyyy} {year} Year. If {yy}, will display the last 2 digits only.
{t} {tt} am/pm string. {tt} will be 2 characters. If the first letter of any of these tokens is capitalized, the resulting string will also be capitalized.
{tz} {timezone} {isotz} {isotimezone} Timezone. If iso prefix, will display in ISO format (ex. "+09:00").

The formats short, long, and full are built-in locale-specific formats. In addition to being able to use them by passing a string to Date#format, they also have their own method shortcuts.

Format
Example
Date.short() July 22, 2012
Date.long() July 22, 2012 1:55pm
Date.full() Sunday July 22, 2012 1:55:55pm

Finally there are a few shortcuts to commonly used formats. These may be passed in as a string or used as a constant directly on the date class. The toISOString method is a direct alias for the ISO8601 format. To output other formats in UTC, use the utc method first.

Format
Example
Date.RFC1123 Fri, 25 Aug 1978 12:23:44 GMT+0900
Date.RFC1036 Friday, 08-Aug-78 12:23:44 GMT+0900
Date.ISO8601_DATE 1978-08-25
Date.ISO8601_DATETIME 1978-08-25T12:23:44.432Z
Date.create().short();
Date.create().long();
Date.create().full();
Date.create().format();
Date.create().format('{Weekday} {Month} {dd}, {yyyy}');
Date.create().format('{yyyy}-{MM}-{dd}');
Date.create().format('{12hr}:{mm}:{ss} {tt}');
Date.create().format('{yyyy}-{MM}-{dd}T{hh}:{mm}:{ss}');
Date.create().format(Date.RFC1123);
Date.create().format(Date.RFC1036);
Date.create().format(Date.ISO8601_DATETIME);
Date.create().format('RFC1036');
Date.create().format('full');
Date.create().toISOString();
Date.create().utc(true).format(Date.RFC1123);

Relative Dates

Sugar also makes getting relative dates easy as well. In addition to standard methods that return the numeric offset, the relative method will produce a localized, relative string with the unit adjusted (more on locales below). Passing a callback fn to relative allows you fine-grained control over the formatting, and is useful for displaying relative or static formats conditionally.

Method
Description
unitsAgo() Returns a number that represents units ago.
unitsFromNow() Returns a number that represents units from now.
relative() Called with no arguments, the relative() method will return a relative date string for the current locale.
relative(fn) Passing a callback to relative allows you more control over the resulting output string. fn is passed 4 arguments: the adjusted value, the adjusted unit index (a value of 0-7 representing milliseconds - years), the non-adjusted offset in ms (negative if the date is in the past), and a locale object. If the callback returns a string with formatting tokens in it, it will parse these out. If it returns nothing or any falsy value, it will remain in relative format. This allows the use of relative and absolute dates conditionally.
Date.create('650 seconds ago').relative();
Date.create('6500 seconds ago').relative();
Date.create('34 hours ago').relative();
Date.create('340 hours ago').relative();
Date.create('monday').relative(function(value, unit, ms, loc) { if(ms.abs() > (1).day()) { // Returns an absolute date, but only if the offset is greater than a day. return '{Weekday} {12hr}:{mm}{tt}'; } });

Ranges

Date ranges are a powerful way to encapsulate, compare, and iterate over a span of time. See ranges for more.

Date Locales

Sugar has support for major locales. The easiest way to add them is to simply include the "Locales" package on the customize page. This package contains all locales in a single bundle. If you need specific locales, simply download the source below and add them to your code anywhere after Sugar is initialized.

Name
Code
Link
English en Source
French fr Source
German de Source
Spanish es Source
Italian it Source
Russian ru Source
Finnish fi Source
Swedish sv Source
Danish da Source
Dutch nl Source
Polish pl Source
Portuguese pt Source
Korean ko Source
Japanese ja Source
Simplified Chinese zh-CN Source
Traditional Chinese zh-TW Source

Both date parsing and formatting are supported, including support for relative formats. Locales can be set globally, or can be passed in at the moment of date creation or output, allowing mixing and matching of various languages. You can also extend Sugar with new locales using Date.addLocale.

Although there is only one English locale, the locale tokens en and en-US will trigger month-forward interpretation of ambiguous forward-slash dates. ie. 8/7/2013 will be interpreted as August 7th, 2013. If this behavior isn't desired you can use any other en base locale such as en-UK, en-AU etc.

Method
Description
Date.setLocale(code) Sets the current locale globally.
Date.getLocale(code) Retreives the localization object for code, or the current locale if none is passed. Augmenting the localization object allows you more control over localizations. Refer to lib/locales/ in the Github project to see the kinds of properties that can be set.
Date.addLocale(code, loc) Add a new localization to Sugar's known locales. Refer to lib/locales/ in the Github project to see the format that needs to be followed.
Date.create(str, code) Locale codes can also be passed when creating each date object. Most of the date creation methods listed above allow a locale code to be passed as a second parameter. For those methods with a conflicting second parameter, simply create the Date first and pass it in directly. Note that when parsing code can be fully qualified (ex. "en_US") and if none is available will fall back to a 2 letter code.
format(str, code) Passing in a locale code to format will use that localization to output the date. Whan a formatting string is passed, tokens will be populated with the appropriate fields localized. If no format is passed, the long format will be used.
relative(code) Relative formats can also be localized.
relative(fn, code) Passing a callback to relative allows more control over relative date formatting. fn will receive 4 parameters (see above), the 4th being the localization object for code, or the current locale if none is specified. This object allows access to all the localization information for that locale. If the callback returns a falsy value, the relative format will be used as normal.
Date.create('2008年11月14日', 'ja')
Date.create('dentro de 5 años', 'es')
Date.create('3 октября 2008 года', 'ru')
Date.create('21 octobre 2011', 'fr').format('', 'ko')
Date.create('la settimana prossima', 'it').format('{weekday}', 'pt')
Date.create('580 minutes ago').relative('ko')
Date.create('580 minutes ago').relative('zh-CN')
Date.create('580 minutes ago').relative('zh-TW')
Date.create('580 minutes ago').relative('it')
Date.create('580 minutes ago').relative('es')
Date.create('580 minutes ago').relative('de')

UTC Dates

Parsing

Sugar has the ability to create dates from a format that is based on UTC (Universal Time). This is a common pattern when accepting server-side dates that are coordinated to UTC time. To indicate to Sugar that a date is utc, call Date.utc.create where you would normally call Date.create. This utc object also has the methods past and future. Note also that if your date is in standard ISO8601 format "0000-00-00T00:00:00Z", the date will automatically be parsed as utc. In ISO8601 this is indicated by the "Z" flag.

Manipulating

Although the above parsing methods will correctly parse a utc date, the date itself is still returned localized. This is the most common pattern as client-side scripting often requires a localized date (i.e. displaying to a user, etc). However, Sugar is also capable of manipulating the dates as if they were utc. This is accomplished by setting an internal flag that tells Sugar to use native UTC methods. This flag is set by the utc method on date instances. Once this flag is set, any date manipulations will be calibrated to utc time, and date formatting will have a zero timezone offset. Finally, note that calling clone on the date will preserve it's utc flag.

Date.utc.create('August 12th, 2003', 'en')
Date.utc.create('August 12th, 2003', 'en').getHours()
Date.create('August 12th, 2003', 'en')
Date.create('August 12th, 2003', 'en').getHours()
new Date().beginningOfDay()
new Date().beginningOfDay().getHours()
new Date().utc(true).beginningOfDay()
new Date().utc(true).beginningOfDay().getHours()

Timezones

As many developers are painfully aware, client-side Javascript has knowledge of only a single timezone, that of the local client. This makes working with other timezones difficult. Although dealing with timezones is outside the scope of Sugar, it does offer a few options to make working timezone-aware libraries easier.

First, it should be noted that if you're interested only in dealing with UTC time and don't need full-blown timezone support, using the simple UTC methods provided by Sugar is a much simpler solution.

Although it's possible to create dates and feed them into a timezone library (or manipulate them yourself to simulate a timezone offset), this will render many of Sugar's convenient methods unusable due to the way dates are internally created. For example, if you wanted to do a simple date comparison to check if the date is in the future, Sugar would internally construct a new date (in the client's locale) to compare against.

Date.SugarNewDate is a hook that allows you to intercept dates just after they are created and perform manipulations on them. They can then properly be used for comparison, etc.

Date.SugarNewDate = function () { var d = new Date(); // Uncommenting the following line effectively sets newly created dates // to GMT-10 hours, the timezone in Honolulu. // d.addMinutes(d.getTimezoneOffset() - 600); return d; };

As long as this function returns a date or object that "speaks" the date methods, Sugar can use it internally. This code example is live so try manipulating it, and see how it affects other dates being created dynamically on this page!

Also note that this example does a very simple operation of subtracting an offset in minutes. Determining local time accurately is often much more difficult, mostly due to issues with DST (Daylight Savings Time).