Date() in different timezone

Posted on
  • I wanted to add clock in a different tz (on bangle.js). I looked at Date() and it has no API to obtain Date in custom tz, is that right?

    Timezones could also be useful for setting clock offset which is now an unfriendly number.

    M

  • There's no way built into Date itself. I don't think it's part of the JS spec?

    If it is then show me where and I'll be happy to add it to Espruino though.

    You could change the timezone globally just while you access date:

    var tz = (new Date()).getTimezoneOffset();
    E.setTimeZone(6);
    var d = new Date();
    // access date here
    E.setTimeZone(tz/60); // return to default
    

    But IMO the most sane thing is just to add/subtract what you need from the hours:

    var timezone = 1;
    var d = new Date(Date.now()+timezone*3600000);
    print(new Date(), d)
    // Date: Wed Jul 1 2020 08:14:48 GMT+0000 
    // Date: Wed Jul 1 2020 09:14:48 GMT+0000
    

    It'll still report GMT+0000, but everything else is as you want it

  • This lib looks quite sane https://momentjs.com/timezone/ (MIT license). Is there a way to include something like that?

    // hypothetical conversion for display of current time in different timezone
    var now = moment(Date().toISOString())
    now.tz('America/Los_Angeles').format('ha­ z');  // 5am PDT
    

    For me js is still mystery so no idea where .format() in the above comes from...

  • Hmm, in emulator I get

    >Uncaught Error: Function "getTimezoneOffset" not found!
     at line 41 col 21
          var tz = Date.getTimezoneOffset();
                        ^
    

    Another problem I run into changing timezone in E and resetting is to pull another Date is I have to pull Date 2 times and the minutes could be off (59 in one, 00 in other)....

  • Just changed the above - it should be (new Date()).getTimezoneOffset()

    But honestly I'd just use the second option... It's a bit cleaner IMO.

    I have to pull Date 2 times

    I'm not sure I understand? Once you have d set up that's all you need - no need to call Date again until the next time you draw.

  • I want to display consistent:

    • current time in currently configured TZ and
    • current time UTC (or any other TZ)
      on current vertical clock (instead Steps which is not working anyway).

    The below works in emu (to show current tz and UTC) but only for the short time using E approach (but what if to new Date() calls span the minute...i.e one is in prev minute, other is in the next?).

    For the second approach the added value would be 0 for UTC but it does not work....

    require("Font8x12").add(Graphics);
    let HRMstate = false;
    let currentHRM = "CALC";
    
    
    function drawTimeDate() {
      var d = new Date();
      var h = d.getHours(), m = d.getMinutes(), day = d.getDate(), month = d.getMonth(), weekDay = d.getDay();
    
      var daysOfWeek = ["SUN", "MON", "TUE","WED","THU","FRI","SAT"];
      var hours = (" "+h).substr(-2);
      var mins= ("0"+m).substr(-2);
      var date = `${daysOfWeek[weekDay]}|${day}|${("0"+(m­onth+1)).substr(-2)}`;
    
    
      // Reset the state of the graphics library
      g.reset();
      // Set color
      g.setColor('#2ecc71');
      // draw the current time (4x size 7 segment)
      g.setFont("8x12",9);
      g.setFontAlign(-1,0); // align right bottom
      g.drawString(hours, 25, 65, true /*clear background*/);
      g.drawString(mins, 25, 155, true /*clear background*/);
    
      // draw the date (2x size 7 segment)
      g.setFont("6x8",2);
      g.setFontAlign(-1,0); // align right bottom
      g.drawString(date, 20, 215, true /*clear background*/);
      
      drawOtherTimezone(d, 0);
    }
    
    
    //We will create custom "Widgets" for our face.
    
    function drawOtherTimezone(d, tzOffset) {
      //Reset to defaults.
      g.reset();
      
      // calculate the other tz date
      var currentTz = d.getTimezoneOffset(); // -6 for me now in emu
      E.setTimeZone(tzOffset);
      var d2 = new Date();
      E.setTimeZone(currentTz); // return to default
      
      /*
      var d2 = new Date(d2+tzOffset*3600000);
      */
    
      var h = d2.getHours(), m = d2.getMinutes(), day = d2.getDate(), month = d2.getMonth(), weekDay = d2.getDay();
      var hoursMins = (" "+h).substr(-2)+":"+("0"+m).substr(-2);
    
      // draw the other tz date
      g.setColor('#7f8c8d');
      g.setFont("8x12",2);
      g.setFontAlign(-1,0); // align right bottom
      g.drawString("UTC+"+tzOffset, 145, 40, true /*clear background*/);
      g.setColor('#bdc3c7');
      g.drawString(hoursMins, 145, 65, true /*clear background*/);
    }
    
    function drawBPM(on) {
      //Reset to defaults.
      g.reset();
      g.setColor('#7f8c8d');
      g.setFont("8x12",2);
      g.setFontAlign(-1,0);
      var heartRate = 0;
    
      if(on){
        g.drawString("BPM", 145, 105, true);
        g.setColor('#e74c3c');
        g.drawString("*", 190, 105, false);
        g.setColor('#bdc3c7');
        //Showing current heartrate reading.
        heartRate = currentHRM.toString() + "    ";
        return g.drawString(heartRate, 145, 130, true /*clear background*/);
      } else {
        g.drawString("BPM  ", 145, 105, true /*clear background*/);
        g.setColor('#bdc3c7');
        return g.drawString("-    ", 145, 130, true); //Padding
      }
    }
    
    function drawBattery() {
      let charge = E.getBattery();
      //Reset to defaults.
      g.reset();
      // draw the date (2x size 7 segment)
      g.setColor('#7f8c8d');
      g.setFont("8x12",2);
      g.setFontAlign(-1,0); // align right bottom
      g.drawString("CHARGE", 145, 170, true /*clear background*/);
      g.setColor('#bdc3c7');
      g.drawString(`${charge}%`, 145, 195, true /*clear background*/);
    }
    
    
    // Clear the screen once, at startup
    g.clear();
    
    // draw immediately at first
    drawTimeDate();
    drawBPM();
    drawBattery();
    
    var secondInterval = setInterval(()=>{
      drawTimeDate();
    }, 15000);
    
    // Stop updates when LCD is off, restart when on
    Bangle.on('lcdPower',on=>{
      if (on) {
        secondInterval = setInterval(()=>{
          drawTimeDate();
        }, 15000);
        //Screen on
        drawBPM(HRMstate);
        drawTimeDate();
        drawBattery();
      } else {
        //Screen off
        clearInterval(secondInterval);
      }
    });
    
    // Show launcher when middle button pressed
    setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
    
    Bangle.on('touch', function(button) {
      if(button == 1 || button == 2){
        Bangle.showLauncher();
      }
    });
    
    //HRM Controller.
    setWatch(function(){
      if(!HRMstate){
        console.log("Toggled HRM");
        //Turn on.
        Bangle.buzz();
        Bangle.setHRMPower(1);
        currentHRM = "CALC";
        HRMstate = true;
      } else if(HRMstate){
        console.log("Toggled HRM");
        //Turn off.
        Bangle.buzz();
        Bangle.setHRMPower(0);
        HRMstate = false;
        currentHRM = [];
      }
      drawBPM(HRMstate);
    }, BTN1, { repeat: true, edge: "falling" });
    
    Bangle.on('HRM', function(hrm) {
      if(hrm.confidence > 90){
        /*Do more research to determine effect algorithm for heartrate average.*/
        console.log(hrm.bpm);
        currentHRM = hrm.bpm;
        drawBPM(HRMstate);
      }
    });
    
    
    //Bangle.on('step', function(up) {
    //  console.log("Step");
    //});
    
    

    1 Attachment

  • Is the issue with the second approach just that your timezone is already nonzero, so what you need is just:

    var timezone = 1;
    var currentTimezone =  (new Date()).getTimezoneOffset();
    var d = new Date(Date.now()+(timezone-currentTimezon­e)*3600000);
    print(new Date(), d)
    
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Date() in different timezone

Posted by Avatar for Michaelnik @Michaelnik

Actions