Save 37% off PRO during our Black Friday Sale! »

Time is but an Illusion.. in JavaScript! (JSConf JP)

378d128c94a9d1a56d873d08b97258a5?s=47 Jenn
December 01, 2019

Time is but an Illusion.. in JavaScript! (JSConf JP)

With so much to worry about timing wise: formatting, time zones, internationalization, recurrence rules, leap years, daylight savings time, and more, everyone needs HELP!

Let’s turn time into money by taking a look at the most popular time libraries and how we use them to solve JavaScript’s time problems. We’ll look at how JavaScript’s Date object started and what its prototype allows. We’ll wind our way through dates, times, and standards to find solutions to the weirdness.

Let’s kill time together talking about JavaScript time! Because we know, time heals all.



December 01, 2019


  1. @mybluewristband TIME.. IS BUT AN ILLUSION IN JAVASCRIPT! @mybluewristband

  2. @mybluewristband ୭Ͱ͔͢? Who am i? @mybluewristband

  3. @mybluewristband Jennifer Wong Mode analytics Mozilla tech speaker whovian

  4. @mybluewristband DOCTOR WHO Time Lord Sonic Screwdriver T.A.R.D.I.S Daleks @mybluewristband

  5. @mybluewristband @mybluewristband

  6. @mybluewristband Ͳ͏ͯ͠? What happened?

  7. @mybluewristband RECURRING INVITES A past project @mybluewristband

  8. @mybluewristband RECURRING INVITES Generate an recurrence rule (rrule) on the

    frontend (???) in iCal format All existing rrule libraries were 1.5+ years out of date But now there is an updated one: So I wrote my own rrule library… Ensure timezone attached to rrule Timezone of office location, not employee Employees are based all over the world May create invites for people in other offices
  9. @mybluewristband @mybluewristband

  10. @mybluewristband @mybluewristband

  11. @mybluewristband FREQ=WEEKLY; BYDAY=FR; UNTIL=20190629T120000Z;

  12. @mybluewristband RECURRING INVITES - A PROBLEM We were in PST

    or GMT-7/GMT-8 (daylight savings) All tests would pass locally At 4pm/5pm PST/PDT, all frontend CI tests would fail for a few hours
  13. @mybluewristband RECURRING INVITES - A PROBLEM Some tests written with

    assuming a specific time zone (PST/PDT) But the CI server was in a different timezone Tests didn’t expect that times minutes or hours apart might be in different days
  14. @mybluewristband RECURRING INVITES - A SOLUTION KINDA Local testing vs

    CI testing issues Resolution: set a particular time/time zone in a test But this only reliably tests that specific time/time zone Also, undo any time mocking or the next test(s) will use the same time/time zone (and probably fail)
  15. “ @mybluewristband Don't write your own recurrence rule library. Doubly

    so for JavaScript. Jennifer Wong
  16. “ @mybluewristband Check the timezone of your CI server. Doubly

    so if it's running JavaScript tests. Jennifer Wong
  17. @mybluewristband ࣌ؒͷෆࢥٞ͞ Time is weird. @mybluewristband

  18. @mybluewristband @mybluewristband

  19. @mybluewristband ࣌ؒ Tale as old as time @mybluewristband

  20. @mybluewristband HISTORY OF TIME Artifacts from Paleolithic era suggest

    the moon was used to reckon time Lunar calendars Earliest lunar calendar was discovered in 8000 BC. Years of either 12 or 13 lunar months (354 or 384 days) Egyptians created first time measurement devices T-square Sundial Water clock
  21. @mybluewristband TYPES OF TIME ZONES OR STANDARDS Greenwich Mean Time

    (GMT) Created in 1847 at the Royal Observatory in Greenwich Universal Coordinated Time (UTC) International Meridian Conference (of 26 nations) $ Colombia was there! & The United States was there! Unix Time Number of seconds that have passed since the Unix Epoch 00:00:00 UTC Thursday, 1 January 1970 International Standards Organization (ISO)
  22. @mybluewristband G M T !!! @mybluewristband

  23. @mybluewristband JAVASCRIPT DATE OBJECT It's old

  24. @mybluewristband @mybluewristband

  25. @mybluewristband ECMA-262 JavaScript! Version 1 - 1997 Only six new

    Date object methods have been added since then Date.prototype.toDateString() Date.prototype.toISOString() Date.prototype.toJSON() Date.prototype.toLocaleDateString() Date.prototype.toLocaleTimeString() Date.prototype.toTimeString()
  26. @mybluewristband WHY THE 0 INDEX JavaScript’s Date object has a

    zero indexed month java.util.Date had 0-indexed month java.time package was released in 2014 with a 1-indexed month Moment.js uses a zero indexed month
  27. @mybluewristband javascripts-date-constructor/41992352#41992352

  28. @mybluewristband javascripts-date-constructor/41992352#41992352

  29. “ @mybluewristband Because Java. Brendan Eich (creator of JavaScript)

  30. @mybluewristband @mybluewristband

  31. @mybluewristband TYPE COERCION One can coerce a date to a

    number of milliseconds from the Unix Epoch simply by using: +new Date() @mybluewristband
  32. @mybluewristband JAVASCRIPT VERSUS MOMENT.JS FIGHT! @mybluewristband

  33. @mybluewristband GETTERS Go get 'em

  34. // Date Object Date.prototype.constructor Date.prototype.getDate() Date.prototype.getDay() Date.prototype.getFullYear() Date.prototype.getHours() Date.prototype.getMilliseconds() Date.prototype.getMinutes()

    Date.prototype.getMonth() Date.prototype.getSeconds() Date.prototype.getTime() Date.prototype.getTimezoneOffset() // Moment.js moment() moment().date() moment().day() moment().year() moment().hour() moment().millesecond() moment().minute() moment().month() moment().second() moment().get() moment().zone() // deprecated @mybluewristband
  35. // Date Object Date.prototype.getUTCDate() Date.prototype.getUTCDay() Date.prototype.getUTCFullYear() Date.prototype.getUTCHours() Date.prototype.getUTCMilliseconds() Date.prototype.getUTCMinutes() Date.prototype.getUTCMonth()

    Date.prototype.getUTCSeconds() // Moment.js moment().utc().date() moment().utc().day() moment().utc().year() moment().utc().hour() moment().utc().milleseconds() moment().utc().minutes() moment().utc().month() moment().utc().seconds() @mybluewristband
  36. @mybluewristband SETTERS Get, set, match (?) @mybluewristband

  37. // Date Object Date.prototype.setDate() Date.prototype.setFullYear() Date.prototype.setHours() Date.prototype.setMilliseconds() Date.prototype.setMinutes() Date.prototype.setMonth() Date.prototype.setSeconds()

    Date.prototype.setTime() Date.prototype.setYear() // deprecated // Moment.js moment().date() moment().year() moment().hour() moment().millesecond() moment().minute() moment().month() moment().second() moment().set() moment().year() @mybluewristband
  38. // Date Object Date.prototype.setUTCDate() Date.prototype.setUTCFullYear() Date.prototype.setUTCHours() Date.prototype.setUTCMilliseconds() Date.prototype.setUTCMinutes() Date.prototype.setUTCMonth() Date.prototype.setUTCSeconds()

    // Moment.js moment().utc().date() moment().utc().year() moment().utc().hour() moment().utc().milleseconds() moment().utc().minutes() moment().utc().month() moment().utc().seconds() @mybluewristband
  39. @mybluewristband OTHER METHODS I've got gadgets and gizmos a-plenty @mybluewristband

  40. @mybluewristband

  41. // Date Object Date.prototype.toDateString() Date.prototype.toISOString() Date.prototype.toJSON() Date.prototype.valueOf() // Returns milliseconds

    since // the Unix epoch which is // 1 January 1970 00:00:00 UTC // Moment.js moment().format('ddd MMM DD YYYY’) moment().utc().format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z' moment().utc().format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z' parseInt( moment().format('x'), 10 ) // Returns the string version of milliseconds since // Unix epoch then parses into an integer @mybluewristband
  42. // Date Object Date.prototype.toString() // e.g. Thu Oct 10 2019

    22:46:02 // GMT-0700 (Pacific Daylight Time) Date.prototype.toTimeString() // e.g. 22:46:02 GMT-0700 // (Pacific Daylight Time) Date.prototype.toUTCString() // e.g. Fri, 11 Oct 2019 // 05:46:02 GMT // Moment.js moment().toDate().toString() // Translate into a Date object // then run .toString() on it moment().toDate().toTimeString() // Translate into a Date object // then run .toString() on it moment().utc().format( 'ddd, DD MMM YYYY HH:mm:ss' ) + ' GMT' @mybluewristband
  43. @mybluewristband LOCALE STRINGS Whoa @mybluewristband

  44. @mybluewristband LOCALE STRINGS Super cool! // Date Object Date.prototype.toLocaleDateString() Date.prototype.toLocaleString()

    Date.prototype.toLocaleTimeString() // Moment.js moment().format('L') moment().format('L, LTS') moment().format(‘LTS') moment().locale()
  45. var event = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));

    var options = { weekday: ‘long', year: ‘numeric', month: ‘long', day: ‘numeric’ }; console.log(event.toLocaleDateString('de-DE', options)); // expected output: Donnerstag, 20. Dezember 2012 console.log(event.toLocaleDateString('ar-EG', options)); // expected output: ٢٠١٢ ،ﺮﺒﻤﺴﯾد ٢٠ ،ﺲﯿﻤﺨﻟا console.log(event.toLocaleDateString('ko-KR', options)); // expected output: 2012֙ 12ਘ 20ੌ ݾਃੌ @mybluewristband
  46. @mybluewristband

  47. None
  48. None
  49. @mybluewristband

  50. @mybluewristband DEPRECATED Returned a two digit OR four digit year

    People didn’t think we’d live beyond the Mayan calendar docs/Web/JavaScript/Reference/ Global_Objects/Date/getYear Date.prototype.getYear() Date.prototype.setYear()
  51. @mybluewristband DEPRECATED Converts a date to a string, using Internet

    Greenwich Mean Time (GMT) conventions Exact format of the return value varies according to the platform and browser… docs/Web/JavaScript/Reference/ Global_Objects/Date/toGMTString Date.prototype.toGMTString()
  52. @mybluewristband NON STANDARD Converts a date to a string using

    the specified formatting Does not use Intl.DateTimeFormat Intl.DateTimeFormat formats dates in a standards-compliant way Deprecated as of Firefox 58+ Date.prototype.toLocaleFormat()
  53. @mybluewristband MOMENT.JS A library! @mybluewristband

  54. @mybluewristband ͳͥMOMENT

  55. @mybluewristband

  56. @mybluewristband MORE GETTERS MOMENT.JS OFFERS moment().quarter() // Returns the year’s

    quarter moment().weekday() // Returns locale aware day of week moment().week() // Returns the week of the year moment().dayOfYear() // Returns the number day of the year from 1-366 moment().weeksInYear() // Returns the number of weeks in a specific year moment().unix() // Unix time in seconds
  57. @mybluewristband DATE TIME MATH IS EASY 1-2-3 moment().add() // Add

    to any part(s) of a date moment().subtract() // Subtract from any part(s) of a date moment().startOf() // Sets any part of a date to the beginning moment().endOf() // Sets any part of a date to the end moment().local() // Set time to the local time zone moment().utc() // Set time to the equivalent UTC time zone moment().utcOffset() // Returns the UTC offset in minutes
  58. @mybluewristband OMG TIMEZONES ⚠ ⚠ ⚠ ⚠ ⚠ ) vs

    & @mybluewristband
  59. @mybluewristband

  60. @mybluewristband Docs: Create moments with timezones Easily edit those

    timezones MOMENT TIMEZONE // Create a moment with a time zone or edit the timezone. { name : 'America/Los_Angeles', // the unique identifier abbrs : ['PDT', 'PST'], // the abbreviations untils : [1414918800000, 1425808800000], // the timestamps in milliseconds offsets : [420, 480] // the offsets in minutes }
  61. @mybluewristband SO, WHAT SHOULD WE USE? Θ͔Γ·ͤΜʜ

  62. @mybluewristband

  63. “ @mybluewristband Just use JavaScript until you can't anymore! Jennifer

  64. @mybluewristband You’ll

  65. @mybluewristband BUT DON’T TAKE MY ADVICE Do what's best for

    your team and your need to scale @mybluewristband
  66. @mybluewristband

  67. @mybluewristband TEMPORAL A tc39 proposal

  68. @mybluewristband

  69. @mybluewristband

  70. @mybluewristband ❤

  71. @mybluewristband ϓϥεα

  72. @mybluewristband Zell Liew for CSS Tricks!

  73. None
  74. @mybluewristband

  75. @mybluewristband ͋Γ͕ͱ͏͟͝ ͍·ͨ͠ʂ ࣭໰ Jennifer Wong @mybluewristband