How to set the timezone on the Pico

Posted on
  • Currently the timezone is set to GMT 0, I want to set it to US Central Time. any ideas on how to do so? I am working with the Pico clock example.

  • I'm afraid it's not quite as easy as changing the zimezone at the moment (I've just filed a bug for it). You can however just change the way the date is created, to create a date that's a few hours in the future or past:

    var timeZone = 2;
    var t = new Date(Date.now()+3600000*timeZone);
    console.log(t.toString());
    
  • Digging up an old post. Was this fixed?

  • No, I'm afraid not.

  • Ok. No problem.

  • what is the bug # and where can we vote for it?

  • I have a computer set to the wrong time zone ( with auto set time turned off, so it reports that. It's the local time in gmt instead of the local time zone) that I use to set the time on my Espruinii...

  • My computer's timezone is set correctly, but the Pico seems to be set to GMT no matter what.

    Here is the code I am using to find out my local sunrise & sunset -- it relies on a variable containing my timezone offset, which I must keep up-to-date based on DST here...

    The trick for me is to just do everything as GMT and then only change for the display

    // myWhere and TZ offset
    var myLatitude = 41.0;
    var myLongitude = -72.0;
    var myTZDeltaMins = -300;
    var gmtDateNow = Date.now();
    
    var suncalc = require("https://raw.githubusercontent.c­om/mourner/suncalc/master/suncalc.js");
    
    function dateLocalTZ( gmtDate, tzMins ) {
      return new Date(gmtDate.getTime() + (tzMins*60000));
    }
    
    function dateStrMinusTZ ( anyDate ) {
      return anyDate.toString().replace(' GMT+0000','');
    }
    
    var gmtTimes = suncalc.getTimes( gmtDateNow, myLatitude, myLongitude );
    var mySunrise = dateLocalTZ(gmtTimes.sunrise,myTZDeltaMi­ns);
    var mySunset = dateLocalTZ(gmtTimes.sunset,myTZDeltaMin­s);
    
    console.log('mySunrise',dateStrMinusTZ(m­ySunrise));
    console.log('mySunset',dateStrMinusTZ(my­Sunset));
    
    if ( (gmtDateNow > gmtTimes.sunrise) && (gmtDateNow < gmtTimes.sunset) ) {
      console.log('it should be light outside');
    } else {
        console.log('it should be dark outside');
    }
    
  • The issue for it is here: https://github.com/espruino/Espruino/iss­ues/530

    It's slightly irritating, but isn't too hard to work around

  • Hi @Gordon,
    I am playing with time zones vs UTC & GMT those days and found this to be a problem:

    new Date().getTimezoneOffset()
    =-60
    >new Date(2019,1,7,10,34-60,19,0)
    =Date: Thu Feb 7 2019 09:34:19 GMT+0100
    >new Date(2019,1,7,9,34+60,19,0)
    =Date: Thu Feb 7 2019 09:34:19 GMT+0100
    >new Date(2019,1,7,8,49+60,19,0)
    =Date: Thu Feb 7 2019 08:49:19 GMT+0100
    >new Date(2019,1,7,0,34-60,19,0)
    =Date: Wed Feb 6 2019 23:34:19 GMT+0100
    >new Date(2019,1,7,0,34+60,19,0)
    =Date: Thu Feb 7 2019 00:34:19 GMT+0100
    

    So, if I use a negative minute, the hour will be correctly handled while using an over 60 minutes minute parameter will not increment the hour....

    This all about gps providing UTC time while I have to handle local day time and winter / summer changes. Beeing in continental Europe, I have an approximative approach (not world wide) which gave me the following functions to get summer / winter day light savings:

    // https://www.calendrier-365.fr/heure-d-et­e-heure-d-hiver.html
    
    function jourFinHiver(annee) { // last sunday of march
      return Math.floor(31.8 - ((((5 * annee) / 4) + 4) % 7));
    }
    
    function jourFinEte(annee) { // last sunday of october
      return Math.floor(31.8 - ((((5 * annee) / 4) + 1) % 7));
    }
    
    function hiver() {
      today= new Date();
      month=1+today.getMonth(); // so 1 based
      if ([1,2,11,12].indexOf(month)>=0) return true;
      if (month===3) return today.getDay() < jourFinHiver(today.getFullYear()); // TDB take care of first hours of day which is still in winter
      if (month===10) return today.getDay() >= jourFinEte(today.getFullYear()); // TDB take care of first hours of day which is still in summer
      return true;
    }
    
    // Set the system time zone in agreement with Uk & Europe day ligth savings (aka winter / summer time) UTCwinterToGMT = 0 for UK, 1 for France/Benelux/Germany...
    function setTimeZone(UTCwinterToGMT) {
      E.setTimeZone(UTCwinterToGMT + (hiver() ? 0 : 1));
    }
    
    // Only valid in Europe (UTC winter to GMT=+1) and UK (UTC winter to GMT = 0)
    function localDayTimeHour(UTCwinterToGMT) { // valid for UTC+1-UTC+2 in continental Europe
      setTimeZone(UTCwinterToGMT); // Handle time zone at system level
      return (new Date().getHours() ) % 24;
    }
    
    

    So references above are in french... Which is fine for me :)

  • It's not entirely surprising that the minute parameter doesn't respond well to out of range minutes. I'm extremely surprised it works on desktop!

    However I've just tweaked Date so new 'cutting edge' - and 2v02+ builds - will have the change in.

    To do stuff like alter the hour what I'd suggest is to:

    Either that or you could keep changing E.setTimeZone depending on how you want the date to appear, which seems to be basically what you're doing?

    I'm actually kind of surprised there's nothing standard in the Date class that allows you to change the timezone on a per-date basis, but it seems not!

  • Yes, I agree that your solution .getTime() seems to be the sole safe solution...
    Thank's again for your reactivity.

    There is no such thing as an uncoherent choice: But that's javascript standards... :)

    1. E.setTimezone takes hours,
    2. new Date().getTimezoneOffset() gives signed minutes,
    3. new Date().getTime() gives ms,
    4. *monthes are 0 based*


    I had dreamed, apparently, to just add the new Date().getTimezone() minutes to the minute parameter of new Date(..., minute, ...) rather than convert everything to ms since 1970, just for simple straight readability.

    To explain a bit more what makes me wondering so much: I get the gps time as 6 bytes in UTC time from ublox M8 binary protocol UBX-NAV-PVT or UBX-NVA-TIMEUTC for instance.
    Here is an excerpt of my code, (this[289].buffer is Uint8Array containing exactly the ublox binary packet (absolutly the all of it, header and checksum included) and d the DataView on it.
    The hidden magic trick here, is that if E.setTimezone(1) is system wide used, the UTC time will be wrong as it is so biaised and you can't see that reading the code: You have to be aware.

      var posGps= {
    ...
    
    get TIMEUTC() {
        if (this[289]===undefined) return undefined;
        let d=new DataView(this[289].buffer);
        return {
          iTOW: d.getUint32(6, true)/1000,
          tAcc: d.getUint32(6+4, true)/1e9,
          nano: d.getInt32(6+8, true)/1e9,
          dateUTC : new Date(d.getUint16(12+6, true), d.getUint8(14+6, true)-1, d.getUint8(15+6, true), d.getUint8(16+6, true), d.getUint8(17+6, true), d.getUint8(18+6, true)),
          valid: d.getUint8(6+19, true),
          receivedAt : new Date(this.receivedAt[289]*1000)
        };
      },
    ...
    }
    
  • Maybe this could help others searching for DST stuff (for Europe at least):

    
    var offsetUTC = 1; // the offset to UTC in Standard Time (winter)
    var useDST = true; // if true, DST will be taken into account when setting TZ
    
    // these formulae are valid until 2099 (or 2022  https://en.wikipedia.org/wiki/Summer_tim­e_in_Europe
    function dayEndWinter(year) { // last Sunday of March
            return Math.ceil(31 - ((((5 * year) / 4) + 4) % 7));
    }
    
    function dayEndSummer(year) { // last Sunday of October
            return Math.ceil(31 - ((((5 * year) / 4) + 1) % 7));
    }
    
    function checkDST(date) {
    
            let year = date.getFullYear();
            let dateStart = new Date(`${year}-03-${dayEndWinter(year)}T0­1:00:00 GMT`);
            let dateEnd = new Date(`${year}-10-${dayEndSummer(year)}T0­1:00:00 GMT`);
      
            return (date >= dateStart && date < dateEnd);
      
    }
    
    function setTimeZone(offsetUTC, useDST) {
            E.setTimeZone(0); // start with UTC
            if (useDST && checkDST(new Date())) {
                offsetUTC += 1; // we're in DST
            }
            E.setTimeZone(offsetUTC);
            console.log('Time after setting TZ: ' + (new Date()).toString());
    }
    
    // sets the TZ with respect to DST
    setTimeZone(offsetUTC, useDST);
    
    // get some start and end dates
    for (let y=2018;y<2023;y++) {
            let dateStart = new Date(`${y}-03-${dayEndWinter(y)}T01:00:0­0 GMT`);
            let dateEnd = new Date(`${y}-10-${dayEndSummer(y)}T01:00:0­0 GMT`);
            console.log(dateStart.toUTCString() + ' till ' + dateEnd.toUTCString());
    }
    
    // test some dates
    let dateStrings = [
            '2019-01-01T00:01:00 GMT', // DST false
            '2019-03-31T00:01:00 GMT', // DST false
            '2019-03-31T02:01:00 GMT', // DST true
            '2019-08-01T00:01:00 GMT', // DST true
            '2019-10-27T00:01:00 GMT', // DST true
            '2019-10-27T01:01:00 GMT', // DST false
            '2019-12-01T00:01:00 GMT', // DST false
    ];
    dateStrings.forEach(function (dateString) {
            let date = new Date(dateString);
            console.log('Checking date ' + date.toString() + ': ' + checkDST(date));
    })
    
    
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

How to set the timezone on the Pico

Posted by Avatar for Vnge @Vnge

Actions