sherb
sherb

Reputation: 6095

Ionic 2 beta 11: Initializing datetime component to account for local timezone

I'm having trouble with the datetime component in Ionic 2 beta 11. From what I gather in the Ionic API documentation, I should pass in a value from Date.toISOString. This works fine, except the date is displayed as UTC instead of the device's current timezone (PDT for my purposes). For example, the date appears as:

09/19/2016 8:46 PM

instead of the expected:

09/19/2016 1:46 PM

Here's my backing class:

export class TestPage {
  private _date: Date = new Date();
  public get date(): string {
    return this._date.toISOString();
  }
}

Any my template code for TestPage:

  <ion-datetime 
      displayFormat="MM/DD/YYYY h:mm A" 
      pickerFormat="MM DD YYYY h mm A" 
      [(ngModel)]="date">
  </ion-datetime>

I can work around this by applying the Date.getTimezoneOffset to the date value first, but I'd rather avoid this since it seems that the framework should be accounting for timezone in the UI.

  public get date(): string {
    let n: number = this._date.getTime();
    n -= (this._date.getTimezoneOffset() * 60 * 1000);
    let d: string = new Date(n).toISOString();
    return d;
  }

Here's a Plunker I've created to demonstrate the issue: http://plnkr.co/edit/2iJRh1zM4pmwcNilWIcG?p=preview

Upvotes: 2

Views: 4148

Answers (2)

FRL
FRL

Reputation: 776

My scenary odata services,return datetimes as ISO 8601 UTC

{ExpectedEndDate:"2016-12-01T04:00:00Z"}

I use pipe to show in primeng DataTable

<p-column field="ExpectedEndDate" header="F.Prevista">
            <template let-col let-item="rowData" pTemplate type="body">
                <span>{{item[col.field] | date: 'dd/MM/yyyy HH:mm:ss'}}</span>
            </template>
</p-column>

this show the date in my local time as expected (GMT+0100)

01/12/2016 05:00:00

Using Ionic DateTime over my model's property, show the edited date as UTC :( for solve i do this in my form.ts Declare 2 functions (i presume can be some kind of global)

setIonicDateTime(value: string): Date {
    if (value) {
        let date: Date = new Date(value);
        let ionicDate = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());
        return ionicDate;
    }
    return null;
}
getIonicDateTime(value: Date): string {
    if (value) {
        let date: Date = new Date(value);
        let ionicDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
        return ionicDate.toISOString();
    }
    return null;
}

then wrap my model propery (edit is my model)

@Input() set ExpectedEndDate(value: string) {
    this.edit.ExpectedEndDate = this.setIonicDateTime(value);
}
get ExpectedEndDate():string {
   return this.getIonicDateTime(this.edit.ExpectedEndDate);
}

in the template the code for for the date use the property instead of model one.

<ion-item>
    <ion-label floating>F.Prevista</ion-label>
    <ion-datetime formControlName="ExpectedEndDate"   displayFormat="DD/MM/YYYY HH:mm" [(ngModel)]="ExpectedEndDate">
    </ion-datetime>
</ion-item>

This way works fine for me, allways show and edit the dates in local time and store in UTC. this work allways the dates are ISO 8601 UTC

Upvotes: 0

sebaferreras
sebaferreras

Reputation: 44659

Like you can see in the docs:

If datetime values need to be parsed from a certain format, or manipulated (such as adding 5 days to a date, subtracting 30 minutes, etc.), or even formatting data to a specific locale, then we highly recommend using moment.js to "Parse, validate, manipulate, and display dates in JavaScript". Moment.js has quickly become our goto standard when dealing with datetimes within JavaScript, but Ionic does not prepackage this dependency since most apps will not require it, and its locale configuration should be decided by the end-developer.

So instead of doing it manually by using Date.getTimezoneOffset you could use timezone methods from moment-timezone.js like this:

var jun = moment("2014-06-01T12:00:00Z");
jun.tz('America/Los_Angeles').format('MM/DD/YYYY h:mm a');

or just:

var timestamp = 1412144245453; // October 1st, 2014 6:17:25 AM.
moment.tz(timeStamp, 'America/Los_Angeles').format('MM/DD/YYYY h:mm a');  // Output: 09/30/2014 11:17 PM

You can check how to import it to the Ionic project here.

Upvotes: 2

Related Questions