Merge lp:~jjacobs/methanal/utc-times into lp:methanal

Proposed by Jonathan Jacobs
Status: Merged
Approved by: Tristan Seligmann
Approved revision: 107
Merged at revision: not available
Proposed branch: lp:~jjacobs/methanal/utc-times
Merge into: lp:methanal
Diff against target: 370 lines
4 files modified
methanal/js/Methanal/Tests/TestUtil.js (+34/-18)
methanal/js/Methanal/Tests/TestView.js (+3/-3)
methanal/js/Methanal/Util.js (+72/-42)
methanal/js/Methanal/View.js (+7/-1)
To merge this branch: bzr merge lp:~jjacobs/methanal/utc-times
Reviewer Review Type Date Requested Status
Tristan Seligmann Approve
Review via email: mp+13124@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Tristan Seligmann (mithrandi) wrote :

> 7 self._knownTime = Methanal.Util.Time.fromDate(
> 8 - new Date(2009, 8, 6, 1, 36, 23, 2));
> 9 + new Date(2009, 8, 6, 1, 36, 23, 2), true);

As far as I can tell, fromDate only takes one parameter; what is the point of passing true here?

review: Needs Information
Revision history for this message
Jonathan Jacobs (jjacobs) wrote :

> > 7 self._knownTime = Methanal.Util.Time.fromDate(
> > 8 - new Date(2009, 8, 6, 1, 36, 23, 2));
> > 9 + new Date(2009, 8, 6, 1, 36, 23, 2), true);
>
> As far as I can tell, fromDate only takes one parameter; what is the point of
> passing true here?

Something left in from an older API. I've removed it and pushed a new revision.

Revision history for this message
Tristan Seligmann (mithrandi) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'methanal/js/Methanal/Tests/TestUtil.js'
--- methanal/js/Methanal/Tests/TestUtil.js 2009-10-02 01:16:09 +0000
+++ methanal/js/Methanal/Tests/TestUtil.js 2009-10-09 22:36:14 +0000
@@ -220,17 +220,20 @@
220 function assertTimeParsed(data, timestamp) {220 function assertTimeParsed(data, timestamp) {
221 var time = Methanal.Util.Time.guess(data);221 var time = Methanal.Util.Time.guess(data);
222 self.assertIdentical(time._oneDay, true);222 self.assertIdentical(time._oneDay, true);
223 self.assertIdentical(time.asTimestamp(), timestamp);223 // User input is interpreted as local time, but the tests should
224 // pass regardless of the runner's local timezone, so we use UTC
225 // dates.
226 self.assertIdentical(time.asUTCDate().getTime(), timestamp);
224 };227 };
225228
226 assertTimeParsed('2009/9/1', 1251756000000);229 assertTimeParsed('2009/9/1', 1251763200000);
227 assertTimeParsed('2009.09.01', 1251756000000);230 assertTimeParsed('2009.09.01', 1251763200000);
228 assertTimeParsed('2009-09-01', 1251756000000);231 assertTimeParsed('2009-09-01', 1251763200000);
229 assertTimeParsed('1/9/2009', 1251756000000);232 assertTimeParsed('1/9/2009', 1251763200000);
230 assertTimeParsed('01.09.2009', 1251756000000);233 assertTimeParsed('01.09.2009', 1251763200000);
231 assertTimeParsed('01-09-2009', 1251756000000);234 assertTimeParsed('01-09-2009', 1251763200000);
232 assertTimeParsed('1/9/2009', 1251756000000);235 assertTimeParsed('1/9/2009', 1251763200000);
233 assertTimeParsed('29/2/2008', 1204236000000);236 assertTimeParsed('29/2/2008', 1204243200000);
234 },237 },
235238
236 239
@@ -264,9 +267,9 @@
264 * Create a L{Methanal.Util.Time} instance from a C{Date}.267 * Create a L{Methanal.Util.Time} instance from a C{Date}.
265 */268 */
266 function test_fromDate(self) {269 function test_fromDate(self) {
267 var d = new Date();270 var d = new Date(2009, 8, 1, 12, 34, 56, 78);
268 var t = Methanal.Util.Time.fromDate(d);271 var t = Methanal.Util.Time.fromDate(d);
269 self.assertIdentical(t.asTimestamp(), d.getTime());272 self.assertIdentical(t.asDate().getTime(), d.getTime());
270 },273 },
271274
272275
@@ -309,19 +312,32 @@
309 * Create a L{Methanal.Util.Time} instance from a timestamp in milliseconds.312 * Create a L{Methanal.Util.Time} instance from a timestamp in milliseconds.
310 */313 */
311 function test_fromTimestamp(self) {314 function test_fromTimestamp(self) {
312 var t = Methanal.Util.Time.fromTimestamp(1251759723000);315 var t;
313 self.assertIdentical(t.asHumanly(), 'Tue, 1 Sep 2009 01:02:03 am');316 var timestamp;
317
318 timestamp = 1251766923000;
319 t = Methanal.Util.Time.fromTimestamp(timestamp);
320 self.assertIdentical(t.asUTCDate().getTime(), timestamp);
321 self.assertIdentical(t._timezoneOffset, 0);
322
323 var d = new Date();
324 timestamp = d.getTime();
325 t = Methanal.Util.Time.fromTimestamp(timestamp, d.getTimezoneOffset());
326 self.assertIdentical(t.asUTCDate().getTime(), timestamp);
327 self.assertIdentical(
328 t._timezoneOffset, d.getTimezoneOffset() * 60 * 1000);
314 },329 },
315330
316331
317 /**332 /**
318 * L{Methanal.Util.Time.asDate} converts a Time into a C{Date} representing333 * L{Methanal.Util.Time.asDate} converts a Time into a C{Date} representing
319 * the same time.334 * the same I{local} time.
320 */335 */
321 function test_asDate(self) {336 function test_asDate(self) {
322 var t = Methanal.Util.Time();337 var t = Methanal.Util.Time();
323 var d = t.asDate();338 var d = t.asDate();
324 self.assertIdentical(t.asTimestamp(), d.getTime());339 self.assertIdentical(
340 t.asTimestamp() + d.getTimezoneOffset() * 60 * 1000, d.getTime());
325 },341 },
326342
327343
@@ -330,7 +346,7 @@
330 * milliseconds elapsed since the epoch.346 * milliseconds elapsed since the epoch.
331 */347 */
332 function test_asTimestamp(self) {348 function test_asTimestamp(self) {
333 self.assertIdentical(self._knownTime.asTimestamp(), 1252193783002);349 self.assertIdentical(self._knownTime.asTimestamp(), 1252200983002);
334 },350 },
335351
336352
@@ -392,11 +408,11 @@
392 */408 */
393 function test_offset(self) {409 function test_offset(self) {
394 var t = self._knownTime.offset(Methanal.Util.TimeDelta({'days': -1}));410 var t = self._knownTime.offset(Methanal.Util.TimeDelta({'days': -1}));
395 self.assertIdentical(t.asTimestamp(), 1252107383002);411 self.assertIdentical(t.asTimestamp(), 1252114583002);
396 self.assertIdentical(t.oneDay().asHumanly(), 'Sat, 5 Sep 2009');412 self.assertIdentical(t.oneDay().asHumanly(), 'Sat, 5 Sep 2009');
397413
398 var t = self._knownTime.offset(Methanal.Util.TimeDelta({'days': 1}));414 var t = self._knownTime.offset(Methanal.Util.TimeDelta({'days': 1}));
399 self.assertIdentical(t.asTimestamp(), 1252280183002);415 self.assertIdentical(t.asTimestamp(), 1252287383002);
400 self.assertIdentical(t.oneDay().asHumanly(), 'Mon, 7 Sep 2009');416 self.assertIdentical(t.oneDay().asHumanly(), 'Mon, 7 Sep 2009');
401 });417 });
402418
403419
=== modified file 'methanal/js/Methanal/Tests/TestView.js'
--- methanal/js/Methanal/Tests/TestView.js 2009-10-04 11:18:09 +0000
+++ methanal/js/Methanal/Tests/TestView.js 2009-10-09 22:36:14 +0000
@@ -525,8 +525,8 @@
525 self.assertIdentical(called, 0);525 self.assertIdentical(called, 0);
526 control.setValue('2009-01-01');526 control.setValue('2009-01-01');
527 self.assertIdentical(called, 1);527 self.assertIdentical(called, 1);
528 self.assertIdentical(displayValue,528 var t = Methanal.Util.Time.fromDate(new Date(2009, 0, 1));
529 Methanal.Util.Time.guess('2009-01-01').asHumanly());529 self.assertIdentical(displayValue, t.oneDay().asHumanly());
530 control.onKeyUp(control.inputNode);530 control.onKeyUp(control.inputNode);
531 self.assertIdentical(called, 2);531 self.assertIdentical(called, 2);
532 });532 });
@@ -548,7 +548,7 @@
548 control.setValue('NOTAVALIDDATE');548 control.setValue('NOTAVALIDDATE');
549 self.assertIdentical(control.getValue(), undefined);549 self.assertIdentical(control.getValue(), undefined);
550 control.setValue('2009-01-01');550 control.setValue('2009-01-01');
551 self.assertIdentical(control.getValue(), 1230760800000);551 self.assertIdentical(control.getValue(), 1230768000000);
552 });552 });
553 },553 },
554 554
555555
=== modified file 'methanal/js/Methanal/Util.js'
--- methanal/js/Methanal/Util.js 2009-10-02 01:16:39 +0000
+++ methanal/js/Methanal/Util.js 2009-10-09 22:36:14 +0000
@@ -479,26 +479,37 @@
479479
480480
481/**481/**
482 * A high-level object built on top of C{Date}.482 * A high-level time and date object.
483 *483 *
484 * @type _date: C{Date}484 * @type _timestamp: C{Number}
485 * @ivar _date: Underlying Date instance485 * @ivar _timestamp: Number of milliseconds since the epoch:
486 * January 1, 1970, 00:00:00 UTC
486 *487 *
487 * @type _oneDay: C{boolean}488 * @type _oneDay: C{boolean}
488 * @ivar _oneDay: Is this a truncated Time instance?489 * @ivar _oneDay: Is this a truncated Time instance?
489 */490 */
490Divmod.Class.subclass(Methanal.Util, 'Time').methods(491Divmod.Class.subclass(Methanal.Util, 'Time').methods(
491 function __init__(self) {492 function __init__(self) {
492 self._date = new Date();493 var d = new Date();
494 self._timezoneOffset = d.getTimezoneOffset() * 60 * 1000;
495 self._timestamp = d.getTime() - self._timezoneOffset;
493 self._oneDay = false;496 self._oneDay = false;
494 },497 },
495498
496499
497 /**500 /**
498 * C{Date} representation.501 * Local time C{Date} representation.
499 */502 */
500 function asDate(self) {503 function asDate(self) {
501 return self._date;504 return new Date(self._timestamp + self._timezoneOffset);
505 },
506
507
508 /**
509 * UTC C{Date} representation.
510 */
511 function asUTCDate(self) {
512 return new Date(self._timestamp);
502 },513 },
503514
504515
@@ -506,7 +517,7 @@
506 * The number of milliseconds since the epoch.517 * The number of milliseconds since the epoch.
507 */518 */
508 function asTimestamp(self) {519 function asTimestamp(self) {
509 return self._date.getTime();520 return self._timestamp;
510 },521 },
511522
512523
@@ -514,7 +525,7 @@
514 * A human-readable string representation.525 * A human-readable string representation.
515 */526 */
516 function asHumanly(self, twentyFourHours) {527 function asHumanly(self, twentyFourHours) {
517 var _date = self._date;528 var _date = self.asDate();
518 var r = [];529 var r = [];
519 r.push(self.getDayName(true) + ',');530 r.push(self.getDayName(true) + ',');
520 r.push(_date.getDate().toString());531 r.push(_date.getDate().toString());
@@ -522,28 +533,24 @@
522 r.push(_date.getFullYear().toString());533 r.push(_date.getFullYear().toString());
523534
524 if (!self._oneDay) {535 if (!self._oneDay) {
525 function _humanlyTime(dateWithTime, twentyFourHours) {536 var prefix = '';
526 var prefix = '';537 var hours = _date.getHours();
527 var hours = dateWithTime.getHours();538 if (!twentyFourHours) {
528 if (!twentyFourHours) {539 var dm = Methanal.Util.divmod(hours, 12);
529 var dm = Methanal.Util.divmod(hours, 12);540 prefix = dm[0] > 0 ? ' pm' : ' am';
530 prefix = dm[0] > 0 ? ' pm' : ' am';541 hours = dm[1] == 0 ? 12 : dm[1];
531 hours = dm[1] == 0 ? 12 : dm[1];
532 }
533
534 function pad(v) {
535 return Methanal.Util.rjust(v.toString(), 2, '0');
536 };
537
538 var r = [];
539 r.push(hours);
540 r.push(dateWithTime.getMinutes());
541 r.push(dateWithTime.getSeconds());
542 r = Methanal.Util.map(pad, r);
543 return r.join(':') + prefix;
544 }542 }
545543
546 r.push(_humanlyTime(_date, twentyFourHours));544 function pad(v) {
545 return Methanal.Util.rjust(v.toString(), 2, '0');
546 };
547
548 var t = [];
549 t.push(hours);
550 t.push(_date.getMinutes());
551 t.push(_date.getSeconds());
552 t = Methanal.Util.map(pad, t);
553 r.push(t.join(':') + prefix);
547 }554 }
548555
549 return r.join(' ');556 return r.join(' ');
@@ -559,7 +566,7 @@
559 * @rtype: C{String}566 * @rtype: C{String}
560 */567 */
561 function getDayName(self, shortened) {568 function getDayName(self, shortened) {
562 var name = Methanal.Util.Time._dayNames[self._date.getDay()];569 var name = Methanal.Util.Time._dayNames[self.asDate().getDay()];
563 return shortened ? name.substr(0, 3) : name;570 return shortened ? name.substr(0, 3) : name;
564 },571 },
565572
@@ -573,7 +580,7 @@
573 * @rtype: C{String}580 * @rtype: C{String}
574 */581 */
575 function getMonthName(self, shortened) {582 function getMonthName(self, shortened) {
576 var name = Methanal.Util.Time._monthNames[self._date.getMonth()];583 var name = Methanal.Util.Time._monthNames[self.asDate().getMonth()];
577 return shortened ? name.substr(0, 3) : name;584 return shortened ? name.substr(0, 3) : name;
578 },585 },
579586
@@ -585,11 +592,12 @@
585 * @return: A new instance representing the truncated date592 * @return: A new instance representing the truncated date
586 */593 */
587 function oneDay(self) {594 function oneDay(self) {
588 var d = new Date(595 var _date = self.asDate();
589 self._date.getFullYear(),596 _date.setHours(0);
590 self._date.getMonth(),597 _date.setMinutes(0);
591 self._date.getDate());598 _date.setSeconds(0);
592 var t = Methanal.Util.Time.fromDate(d);599 _date.setMilliseconds(0);
600 var t = Methanal.Util.Time.fromDate(_date);
593 t._oneDay = true;601 t._oneDay = true;
594 return t;602 return t;
595 },603 },
@@ -606,9 +614,9 @@
606 * @return: A new instance representing the newly offset time614 * @return: A new instance representing the newly offset time
607 */615 */
608 function offset(self, delta) {616 function offset(self, delta) {
609 var d = new Date(self.asTimestamp() + delta);617 var t = Methanal.Util.Time.fromTimestamp(self.asTimestamp() + delta);
610 var t = Methanal.Util.Time.fromDate(d);
611 t._oneDay = self._oneDay;618 t._oneDay = self._oneDay;
619 t._timezoneOffset = self._timezoneOffset;
612 return t;620 return t;
613 });621 });
614622
@@ -628,17 +636,35 @@
628 */636 */
629Methanal.Util.Time.fromDate = function fromDate(dateObj) {637Methanal.Util.Time.fromDate = function fromDate(dateObj) {
630 var t = Methanal.Util.Time();638 var t = Methanal.Util.Time();
631 t._date = dateObj;639 t._timezoneOffset = dateObj.getTimezoneOffset() * 60 * 1000;
640 t._timestamp = dateObj.getTime() - t._timezoneOffset;
632 return t;641 return t;
633};642};
634643
635644
636645
637/**646/**
638 * Create a L{Methanal.Util.Time} instance from a timestamp in milliseconds.647 * Create a L{Methanal.Util.Time} instance from a timestamp in milliseconds,
648 * since January 1, 1970, 00:00:00 UTC.
649 *
650 * @type timestamp: C{Number}
651 * @param timestamp: Number of milliseconds since the epoch
652 *
653 * @type timezoneOffset: C{Number}
654 * @param timezoneOffset: Timezone offset in minutes
655 *
656 * @rtype: L{Methanal.Util.Time}
639 */657 */
640Methanal.Util.Time.fromTimestamp = function fromTimestamp(timestamp) {658Methanal.Util.Time.fromTimestamp = function fromTimestamp(timestamp, timezoneOffset) {
641 return Methanal.Util.Time.fromDate(new Date(timestamp));659 var t = Methanal.Util.Time();
660 t._timestamp = timestamp;
661 if (timezoneOffset) {
662 timezoneOffset *= 60 * 1000;
663 } else {
664 timezoneOffset = 0;
665 }
666 t._timezoneOffset = timezoneOffset;
667 return t;
642};668};
643669
644670
@@ -715,6 +741,9 @@
715/**741/**
716 * Create a L{Methanal.Util.Time} instance from a semi-structured string.742 * Create a L{Methanal.Util.Time} instance from a semi-structured string.
717 *743 *
744 * As this is primarily intended for textual date input by users, L{value} is
745 * interpreted in local time.
746 *
718 * @type value: C{String}747 * @type value: C{String}
719 * @param value: Either a numerical YYYYMMDD or DDMMYYY string (separated by748 * @param value: Either a numerical YYYYMMDD or DDMMYYY string (separated by
720 * C{/}, C{.} or C{-}) or a relative time reference, as supported by749 * C{/}, C{.} or C{-}) or a relative time reference, as supported by
@@ -759,10 +788,11 @@
759 y = Methanal.Util.strToInt(parts[2]);788 y = Methanal.Util.strToInt(parts[2]);
760 }789 }
761790
762 if (_validDate(y, m, d))791 if (_validDate(y, m, d)) {
763 // TODO: In the future, "guess" should be able to guess times as792 // TODO: In the future, "guess" should be able to guess times as
764 // well as dates.793 // well as dates.
765 return Methanal.Util.Time.fromDate(new Date(y, m, d)).oneDay();794 return Methanal.Util.Time.fromDate(new Date(y, m, d)).oneDay();
795 }
766 }796 }
767797
768 throw new Methanal.Util.TimeParseError(798 throw new Methanal.Util.TimeParseError(
769799
=== modified file 'methanal/js/Methanal/View.js'
--- methanal/js/Methanal/View.js 2009-10-05 00:15:43 +0000
+++ methanal/js/Methanal/View.js 2009-10-09 22:36:14 +0000
@@ -1605,7 +1605,13 @@
1605 function makeDisplayValue(self, value) {1605 function makeDisplayValue(self, value) {
1606 var msg = '';1606 var msg = '';
1607 try {1607 try {
1608 var time = Methanal.Util.Time.fromTimestamp(value).oneDay();1608 // XXX: There is probably a potential bug here: If "value" (a UTC
1609 // timestamp) falls before the switch-over for daylight savings
1610 // before the timezone offset has been corrected for, the timezone
1611 // offset given here will be the wrong one.
1612 var d = new Date(value);
1613 var time = Methanal.Util.Time.fromTimestamp(
1614 value, d.getTimezoneOffset()).oneDay();
1609 if (time) {1615 if (time) {
1610 msg = time.asHumanly(self.twentyFourHours);1616 msg = time.asHumanly(self.twentyFourHours);
1611 }1617 }

Subscribers

People subscribed via source and target branches