Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the Date standard library #357

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions std/assembly/bindings/Date.ts
@@ -1,6 +1,7 @@
export declare function UTC(
// NOTE: Using i32 below saves us a f64.convert_s instruction and moves the responsibility for
// converting the value to the WASM/JS boundary.
// It returns the number of milliseconds since January 1, 1970, 00:00:00 UTC.
year: i32,
month: i32,
day: i32,
Expand All @@ -9,4 +10,7 @@ export declare function UTC(
second: i32,
millisecond: f64
): f64;

export declare function now(): f64;

export declare function getTimezoneOffset(): i32;
222 changes: 221 additions & 1 deletion std/assembly/date.ts
@@ -1,8 +1,21 @@
import {
UTC as Date_UTC,
now as Date_now
now as Date_now,
getTimezoneOffset as Date_getTimezoneOffset
} from "./bindings/Date";

import {
getCalendarDate,
TimeZone,
CalendarDate,
setFullYear,
setMonth,
setDate,
setHours,
setMinutes,
setSeconds,
setMilliseconds
} from "./util/date";
export class Date {

@inline static UTC(
Expand All @@ -22,9 +35,13 @@ export class Date {
}

private value: i64;
private timeZone: TimeZone; // The local time zone
private localDate: CalendarDate | null;
private utcDate: CalendarDate | null;

constructor(value: i64) {
this.value = value;
this.timeZone = new TimeZone("GMT", Date_getTimezoneOffset());
}

getTime(): i64 {
Expand All @@ -35,4 +52,207 @@ export class Date {
this.value = value;
return value;
}

private getLocalCalendarDate(): CalendarDate {
if (this.isNormalizeLocalDate()) {
return this.localDate!;
} else if (this.localDate != null && !this.localDate!.isNormalized) {
return getCalendarDate(this.localDate!, this.value);
} else {
let cdate = new CalendarDate(this.value, this.timeZone);
this.localDate = getCalendarDate(cdate, this.value);
return this.localDate!;
}
}

private getUTCCalendarDate(): CalendarDate {
if (this.isNormalizeUTCDate()) {
return this.utcDate!;
} else if (this.utcDate != null) {
return getCalendarDate(this.utcDate!, this.value);
} else {
let cdate = new CalendarDate(this.value, TimeZone.UTC_TIME_ZONE);
this.utcDate = getCalendarDate(cdate, this.value);
return this.utcDate!;
}
}

private isNormalizeLocalDate(): bool {
return this.localDate != null
&& this.localDate!.millis == this.value
&& this.localDate!.isNormalized;
}

private isNormalizeUTCDate(): bool {
return this.utcDate != null
&& this.utcDate!.millis == this.value
&& this.utcDate!.isNormalized;
}

getFullYear(): i32 {
return this.getLocalCalendarDate().year;
}

/**
* The method sets the full year for a specified date according to local time.
* @param year the full year to set
* @returns Returns new timestamp.
*/
setFullYear(year: i32): i64 {
var cdate = this.getLocalCalendarDate();
setFullYear(cdate, year);
return this.setTime(cdate.millis);
}

getUTCFullYear(): i32 {
return this.getUTCCalendarDate().year;
}

/**
* The setUTCFullYear() method sets the full year for a specified date according to universal time.
* @param year the full year to set.
*/
setUTCFullYear(year: i32): i64 {
var cdate = this.getUTCCalendarDate();
setFullYear(cdate, year);
return this.setTime(cdate.millis);
}

getMonth(): i32 {
return this.getLocalCalendarDate().month - 1; // Adjust 1-based to 0-based
}

setMonth(month: i32): i64 {
var cdate = this.getLocalCalendarDate();
setMonth(cdate, month + 1);
return this.setTime(cdate.millis);
}

getUTCMonth(): i32 {
return this.getUTCCalendarDate().month - 1; // adjust 1-based to 0-based;
}

setUTCMonth(month: i32): i64 {
var cdate = this.getUTCCalendarDate();
setMonth(cdate, month + 1);
return this.setTime(cdate.millis);
}

getDate(): i32 {
return this.getLocalCalendarDate().dayOfMonth;
}

setDate(date: i32): i64 {
var cdate = this.getLocalCalendarDate();
setDate(cdate, date);
return this.setTime(cdate.millis);
}

getUTCDate(): i32 {
return this.getUTCCalendarDate().dayOfMonth;
}

setUTCDate(date: i32): i64 {
var cdate = this.getUTCCalendarDate();
setDate(cdate, date);
return this.setTime(cdate.millis);
}

/**
* Returns the day of the week represented by this date. The
* returned value ({@code 0} = Sunday, {@code 1} = Monday,
* {@code 2} = Tuesday, {@code 3} = Wednesday, {@code 4} =
* Thursday, {@code 5} = Friday, {@code 6} = Saturday)
*/
getDay(): i32 {
return this.getLocalCalendarDate().dayOfWeek - 1 ;
}

getUTCDay(): i32 {
return this.getUTCCalendarDate().dayOfWeek - 1 ;
}

getHours(): i32 {
return this.getLocalCalendarDate().hours;
}

setHours(hours: i32): i64 {
var cdate = this.getLocalCalendarDate();
setHours(cdate, hours);
return this.setTime(cdate.millis);
}

getUTCHours(): i32 {
return this.getUTCCalendarDate().hours;
}

setUTCHours(hours: i32): i64 {
var cdate = this.getUTCCalendarDate();
setHours(cdate, hours);
return this.setTime(cdate.millis);
}

getMinutes(): i32 {
return this.getLocalCalendarDate().minutes;
}

setMinutes(minutes: i32): i64 {
var cdate = this.getLocalCalendarDate();
setMinutes(cdate, minutes);
return this.setTime(cdate.millis);
}

getUTCMinutes(): i32 {
return this.getUTCCalendarDate().minutes;
}

setUTCMinutes(minutes: i32): i64 {
var cdate = this.getUTCCalendarDate();
setMinutes(cdate, minutes);
return this.setTime(cdate.millis);
}

getSeconds(): i32 {
return this.getLocalCalendarDate().seconds;
}

setSeconds(seconds: i32): i64 {
var cdate = this.getLocalCalendarDate();
setSeconds(cdate, seconds);
return this.setTime(cdate.millis);
}

getUTCSeconds(): i32 {
return this.getUTCCalendarDate().seconds;
}

setUTCSeconds(seconds: i32): i64 {
var cdate = this.getUTCCalendarDate();
setSeconds(cdate, seconds);
return this.setTime(cdate.millis);
}

getMilliseconds(): i32 {
return this.getLocalCalendarDate().milliseconds;
}

setMilliseconds(milliseconds: i32): i64 {
var cdate = this.getLocalCalendarDate();
setMilliseconds(cdate, milliseconds);
return this.setTime(cdate.millis);
}

getUTCMilliseconds(): i32 {
return this.getUTCCalendarDate().milliseconds;
}

setUTCMilliseconds(milliseconds: i32): i64 {
var cdate = this.getUTCCalendarDate();
setMilliseconds(cdate, milliseconds);
return this.setTime(cdate.millis);
}

getTimezoneOffset(): i32 {
return Date_getTimezoneOffset();
}
}
70 changes: 66 additions & 4 deletions std/assembly/index.d.ts
Expand Up @@ -1700,15 +1700,77 @@ declare class Date {
minute: i32,
second: i32,
millisecond: i32
): i64;
): number;
/** Returns the current UTC timestamp in milliseconds. */
static now(): i64;
static now(): number;
/** Constructs a new date object from an UTC timestamp in milliseconds. */
constructor(value: i64);
constructor(value: number);
/** Returns the time zone difference, in minutes, from current locale(host system settings) to UTC. */
getTimezoneOffset(): i32;
/** Returns the UTC timestamp of this date in milliseconds. */
getTime(): i64;
getTime(): number;
/** Sets the UTC timestamp of this date in milliseconds. */
setTime(value: i64): i64;
/** Returns the year of the specified date according to local time. */
getFullYear(): i32;
/** Sets the full year for a specified date according to local time. Returns new timestamp. */
setFullYear(year: i32): i64;
/** Returns the month in the specified date according to local time. As a zero-based value (where zero indicates the first month of the year) */
getMonth(): i32;
/** Sets the month for a specified date according to the currently set year. Return UTC milliseconds timestamp. */
setMonth(month: i32): i32;
/** Return the day of the month of this date in milliseconds, 1-based. */
getDate(): i32;
/** Sets the day of the Date object relative to the beginning of the currently set month. */
setDate(date: i32): i64;
/** Returns the day of the week for the specified date according to local time, where 0 represents Sunday */
getDay(): i32;
/** Returns the hours of the specified date according to local time. */
getHours(): i32;
/** sets the hours for a specified date according to local time, and returns the UTC milliseconds timestamps. */
setHours(hours: i32): i64;
/** Returns the minutes of the specified date according to local time. */
getMinutes(): i32;
/** Sets the minutes for a specified date according to local time. */
setMinutes(minutes: i32): i64;
/** Returns the seconds of the specified date according to local time. */
getSeconds(): i32;
/** Sets the seconds for a specified date according to local time. */
setSeconds(seconds: i32): i64;
/** Returns the milliseconds in the specified date according to local time. */
getMilliseconds(): i32;
/** Sets the milliseconds for a specified date according to local time. */
setMilliseconds(milliseconds: i32): i64;
/** Returns the year of the specified date according to UTC timestamp. */
getUTCFullYear(): i32;
/** Sets the full year for a specified date according to UTC timestamp. Returns new timestamp. */
setUTCFullYear(year: i32): i64;
/** Returns the month in the specified date according to UTC timestamp. As a zero-based value (where zero indicates the first month of the year) */
getUTCMonth(): i32;
/** Sets the month for a specified date according to the currently set year. Return UTC milliseconds timestamp. */
setUTCMonth(month: i32): i32;
/** Return the day of the month of this date in milliseconds, 1-based. */
getUTCDate(): i32;
/** Sets the day of the Date object relative to the beginning of the currently set month. */
setUTCDate(date: i32): i64;
/** Returns the day of the week for the specified date according to UTC timestamp, where 0 represents Sunday */
getUTCDay(): i32;
/** Returns the hours of the specified date according to UTC timestamp. */
getUTCHours(): i32;
/** sets the hours for a specified date according to UTC time, and returns the UTC milliseconds timestamps. */
setUTCHours(hours: i32): i64;
/** Returns the minutes of the specified date according to UTC timestamp. */
getUTCMinutes(): i32;
/** Sets the minutes for a specified date according to UTC time. */
setUTCMinutes(minutes: i32): i64;
/** Returns the seconds of the specified date according to UTC timestamp. */
getUTCSeconds(): i32;
/** Sets the seconds for a specified date according to UTC time. */
setUTCSeconds(seconds: i32): i64;
/** Returns the milliseconds in the specified date according to the UTC timestamp. */
getUTCMilliseconds(): i32;
/** Sets the milliseconds for a specified date according to UTC time. */
setUTCMilliseconds(milliseconds: i32): i64;
}

/** Class for representing a runtime error. Base class of all errors. */
Expand Down