Timestamp interpreted different on local machine and on gitlab pipeline

Viewed 1327

I have the following code to convert a timestamp to text format.

export default function convertTime(time) {
    let date = new Date(time);
    let year = date.getFullYear();
    let month = date.getMonth() + 1;
    let day = date.getDate();
    let hours = date.getHours();
    let minutes = "0" + date.getMinutes();
    return day + "." + month + "." + year + " " + hours + ':' + minutes.substr(-2);
}

and my test with jest is the following:

import convertTime from "../../../src/components/Base/TimeConverter";

describe("Test time converter", function () {
    it("Time converter should return valid string for a certain hard coded time stamp in milliseconds", function () {
        const result = convertTime(1585575410 * 1000);
        const expected_result = "30.3.2020 15:36";
        expect(result).toBe(expected_result);
    });
});

on my computer the test passes:

lara@dirk:~/Desktop/git/JS/kiwi$ npm run test

> kiwi@0.1.0 test /home/lara/Desktop/git/JS/kiwi
> env-cmd -f .env.dev jest --passWithNoTests

 PASS  tests/components/Base/TestTimeConverter.spec.js
 PASS  tests/others/TestEnvironmentVariables.spec.js

Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.349s
Ran all test suites.

however on gitlab it fails:

$ npm run test
 > kiwi@0.1.0 test /builds/kiwi4/frontend
 > env-cmd -f .env.dev jest --passWithNoTests
 PASS tests/others/TestEnvironmentVariables.spec.js
 FAIL tests/components/Base/TestTimeConverter.spec.js
   ● Test time converter › Time converter should return valid string for a certain hard coded time stamp in milliseconds
     expect(received).toBe(expected) // Object.is equality
     Expected: "30.3.2020 15:36"
     Received: "30.3.2020 13:36"
       5 |         const result = convertTime(1585575410 * 1000);
       6 |         const expected_result = "30.3.2020 15:36";
     > 7 |         expect(result).toBe(expected_result);
         |                        ^
       8 |     });
       9 | });
       at Object.<anonymous> (tests/components/Base/TestTimeConverter.spec.js:7:24)
 Test Suites: 1 failed, 1 passed, 2 total
 Tests:       1 failed, 1 passed, 2 total

My question is why?

2 Answers

The GitLab runner instance and your computer have different timezone.

Quote from dzone.com

When you call getTime method on Date object you get the number of milliseconds from Unix epoch. Although your current Date object keeps time with some offset getTime gives seconds in UTC. Keep this in mind when creating timestamps if you are not living on zero-meridian.

var currentDate = selectedDate;          

var currentTime = currentDate.getTime(); 

This is pretty awkward, unexpected and unintuitive behavior but you have to keep in mind that all date and time calculations must use same time system to give appropriate results.

You will need to get the attributes in UTC timezone OR calculate the timezone offset with:

new Date(timestamp + (offset * 1000))

And you can calculate the offset of your client with:

const offset = new Date().getTimezoneOffset();

I bet you are located someplace in the US Central Daylight time zone, and gitlab in Pacific. Your test is timezone sensitive. (Hint: when times mismatch by exactly some number of hours, it's usually a timezone problem.)

Javascript's Date methods like .getFullYear() are inherently sensitive to the timezone setting. The methods like .getUTCFullYear() aren't.

You can arrange to run nodejs with the TZ environment variable set so it doesn't accept the local default. You need to do this in your pipeline for this test to pass.

 env TZ='UTC' node yourcommand

Or you can try putting this line of js right at the top of your test.

 process.env.TZ = 'UTC'
Related