HiveBrain v1.2.0
Get Started
← Back to all entries
gotchajavascriptMinor

Difference between API time and server time

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
servertimedifferencebetweenandapi

Problem

I'm using the openweathermap API to get weather forecast data. I want to make sure that the forecast values are at minimum 2 hours in the future. The API is providing the forecast in 3 hour steps, so I need to make sure that the weather data are in the future.

Here is an example response provided by openweathermap API:

{"city":{"id":1851632,"name":"Shuzenji",
"coord":{"lon":138.933334,"lat":34.966671},
"country":"JP",
"cod":"200",
"message":0.0045,
"cnt":38,
"list":[{
"dt":1406106000,
"main":{
"temp":298.77,
"temp_min":298.77,
"temp_max":298.774,
"pressure":1005.93,
"sea_level":1018.18,
"grnd_level":1005.93,
"humidity":87
"temp_kf":0.26},
"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],
"clouds":{"all":88},
"wind":{"speed":5.71,"deg":229.501},
"sys":{"pod":"d"},
"dt_txt":"2014-07-23 09:00:00"}
]}

I'm using JSON. The list property has the value dt_txt in this format: year-month-day 09:00:00. Now I need to check if this DateTime is minimum 2 hours in the future and if not I simply take the item at index 1 of the list.

I wrote following code:

// look for next prediction
var weatherList = parsed.list;

// Check which time is relevant
// Get only time without description or/and date
// 2017-03-17 21:00:00
// ~~~~~~~~~~~~~^
var columnIndex = weatherList[0]["dt_txt"].indexOf(":") - 2;
// 2017-03-17 21:00:00
// ~~~~~~~~~~~^
var apiHoursString  = weatherList[0]["dt_txt"].substring(columnIndex, columnIndex + 2);

// server time:
var hours = String((new Date()).getHours());
if(hours.length < 2){
    hours = "0" + hours;
}

var apiHoursInt = parseInt(apiHoursString);
var hoursInt = parseInt(hours);

if((apiHoursInt - hoursInt) < 2){
    indexToUse = 1
}


I know this code is bad - what is the proper way to do that on Node.js?

Solution

I would not parse the dt_txt field. You would have to make too many assumptions including the format of the date (Is it yyyy-mm-dd or the American mm-dd-yyyy) and the time zone. Instead create a date object from the dt field:

var apiHours = (new Date(weatherList[0].dt * 1000)).getHours();


All those operations to add 0 and do hours to string to integer conversions are redundant. The following should be sufficient:

let weatherList  = parsed.list;
let apiHours     = (new Date(weatherList[0].dt * 1000).getHours();
let serverHours  = (new Date()).getHours();
let indexToUse   = (apiHours - serverHours < 2) ? 1 : 0;


Update 1

David is right, I had missed that point. A better solution would be:

// All values in milliseconds
const oneHour   = 60 * 60 * 1000;
let  apiTime    = weatherList[0].dt * 1000;
let  serverTime = (new Date()).valueOf();
let  indexToUse = (apiTime - serverTime < 2 * oneHour) ? 1 : 0;

Code Snippets

var apiHours = (new Date(weatherList[0].dt * 1000)).getHours();
let weatherList  = parsed.list;
let apiHours     = (new Date(weatherList[0].dt * 1000).getHours();
let serverHours  = (new Date()).getHours();
let indexToUse   = (apiHours - serverHours < 2) ? 1 : 0;
// All values in milliseconds
const oneHour   = 60 * 60 * 1000;
let  apiTime    = weatherList[0].dt * 1000;
let  serverTime = (new Date()).valueOf();
let  indexToUse = (apiTime - serverTime < 2 * oneHour) ? 1 : 0;

Context

StackExchange Code Review Q#158262, answer score: 2

Revisions (0)

No revisions yet.