Reputation: 79
I am pragmatically building a nested JSON from a table. Json looks something like this:
{"date":"03-16-2018 06:57:02",
"details":
[
{
"motorstate":0,
"startTime":"03-16-2018 20:41:57",
},
{
"motorstate":0,
"startTime":"03-16-2018 06:57:02",
}
]
},
{"date":"03-15-2018 08:08:48",
"details":
[
{
"motorstate":0,
"startTime":"03-16-2018 03:53:30",
}
]
}
If you look into the above example, the second record:
{"date":"03-15-2018 08:08:48",
"details":
[
{
"motorstate":0,
"startTime":"03-16-2018 03:53:30",
}
]
}
The dates are mismatching. This is because the date shown here is in IST but actually stored in UTC in my Google Datastore. In UTC, its still 03-15-2018 and not 03-16-2018.
My question is how can we perform a date difference in different timezones other than UTC in Java? The Date.getTime() method always give the difference in UTC and not in local Timezone.
Upvotes: 0
Views: 629
Reputation: 340300
Date difference in different timezones in java
Period.between(
LocalDateTime.parse(
"03-15-2018 08:08:48" ,
DateTimeFormatter.ofPattern( “MM-dd-uuuu HH:mm:ss” )
)
.atZone( ZoneId.of( ”Asia/Kolkata" ) )
.toLocalDate()
,
LocalDate.now( ZoneId.of( ”Asia/Kolkata" ) )
)
The modern approach uses the java.time classes rather than the troublesome old me old legacy date-time classes such as Date
and Calendar
.
Tip: Avoid custom formatting patterns when serializing date-time values to text. Use standard ISO 8601 formats only.
Tip: when exchanging date-time values as text, always include an indicator of the offset-from-UTC and the time zone name.
First, parse your input strings as LocalDateTime
because they lack any indication of offset or zone.
Define a formatting pattern to match input.
DateTimeFormatter f = DateTimeFormatter.ofPattern( “MM-dd-uuuu HH:mm:ss” ) ;
Parse.
String input = "03-15-2018 08:08:48" ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
You claim to know that these inputs were intended to represent a moment in India time. Apply a ZoneId
to get a ZonedDateTime
.
ZoneId z = ZoneId.of( ”Asia/Kolkata" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
To get the date-only value, extract a LocalDate
.
LocalDate ld = zdt.toLocalDate() ;
To represent the delta between dates as a number of years, months, and days unattached to the timeline, use Period
.
Period p = Period.between( ldt , LocalDate.now( z ) ) ;
For a count of total days.
long days = ChronoUnit.DAYS.between( start , stop ) ;
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
Upvotes: 3
Reputation: 121
Below method will return you your UTC time to current Timezone and this worked for me
public static Date getLocalDateObjFromUTC(String date, String time) throws ParseException {
String dateAndTimeInUTC = date + " " + time;
SimpleDateFormat localDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
localDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date dateInLocalTimeZone = localDateFormat.parse(dateAndTimeInUTC);
return dateInLocalTimeZone;
}
Upvotes: 0
Reputation: 79
public String getSummary(String deviceGuid)
{
Query<com.google.cloud.datastore.Entity> query
= Query.newEntityQueryBuilder()
.setKind("sensordata")
.setFilter(PropertyFilter.eq("deviceguid", deviceGuid))
.setOrderBy(OrderBy.desc("startTime"))
.build();
QueryResults<com.google.cloud.datastore.Entity> resultList =
datastore.run(query);
if(!resultList.hasNext())
{
log.warning("No record found..");
return "No record found";
}
com.google.cloud.datastore.Entity e =null;
com.google.cloud.datastore.Entity pe =null;
SensorDataOut sensorDataOut = new SensorDataOut();
SensorSummaryDataOut summary = new SensorSummaryDataOut();
TotalSummaryDataOut totalSummary = new TotalSummaryDataOut();
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("IST"));
Calendar calendar1 = Calendar.getInstance();
calendar1.setTimeZone(TimeZone.getTimeZone("IST"));
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("IST"));
SimpleDateFormat sdf1 = new SimpleDateFormat("MM-dd-yyyy");
//sdf.setTimeZone(TimeZone.getTimeZone("IST"));
long stopTime;
long startTime;
long pStartTime;
long diffTime;
long diffDay;
Date pDateWithoutTime;
Date eDateWithoutTime;
while(resultList.hasNext())
{
e = resultList.next();
startTime = (e.contains("startTime"))?e.getTimestamp("startTime").toSqlTimestamp().getTime():0;
stopTime = (e.contains("stopTime"))?e.getTimestamp("stopTime").toSqlTimestamp().getTime():0;
//log.info("Start Date : " + e.getTimestamp("startTime").toString() + " - " + String.valueOf(startTime));
//log.info("Stop Date : " + e.getTimestamp("stopTime").toString() + " - " + String.valueOf(stopTime));
//log.info("Usage Volume :" + String.valueOf(e.getLong("usageVolume")));
sensorDataOut = new SensorDataOut();
calendar.setTimeInMillis(stopTime);
sensorDataOut.stopTime = sdf.format(calendar.getTime());
calendar.setTimeInMillis(startTime);
sensorDataOut.startTime = sdf.format(calendar.getTime());
sensorDataOut.motorstate = (e.contains("motorstate"))?(int)e.getLong("motorstate"):-1;
sensorDataOut.startVolume = (e.contains("startVolume"))?(int)e.getLong("startVolume"):-1;
sensorDataOut.stopVolume = (e.contains("stopVolume"))?(int)e.getLong("stopVolume"):-1;
sensorDataOut.usageTime = (e.contains("usageTime"))?e.getLong("usageTime"):-1;
sensorDataOut.usageVolume = (e.contains("usageVolume"))?(int)e.getLong("usageVolume"):-1;
if(pe!=null)
{
//Get the date difference in terms of days. If it is same day then add the volume consumed
pStartTime= pe.getTimestamp("startTime").toSqlTimestamp().getTime();
try{
calendar.setTimeInMillis(pStartTime);
pDateWithoutTime = sdf1.parse(sdf1.format(calendar.getTime()));
calendar1.setTimeInMillis(e.getTimestamp("startTime").toSqlTimestamp().getTime());
eDateWithoutTime = sdf1.parse(sdf1.format(calendar1.getTime()));
}
catch(Exception ex){
log.info("Exception while parsing date");
continue;
}
diffTime = Math.abs(pDateWithoutTime.getTime() - eDateWithoutTime.getTime());
diffDay = TimeUnit.DAYS.convert(diffTime, TimeUnit.MILLISECONDS);
//log.info("pDateWithoutTime: " + pDateWithoutTime + ", eDateWithoutTime: " + eDateWithoutTime + ", consumedVolume: "
// + sensorDataOut.usageVolume;
if(diffDay!=0) //If not same day
{
totalSummary.totVolume = totalSummary.totVolume + summary.totVolume;
totalSummary.totDuration = totalSummary.totDuration + summary.totDuration;
totalSummary.details.add(summary);
summary = new SensorSummaryDataOut();
}
}
summary.date = sensorDataOut.startTime;
summary.totVolume = summary.totVolume + sensorDataOut.usageVolume;
summary.totDuration = summary.totDuration + sensorDataOut.usageTime;
summary.details.add(sensorDataOut);
pe = e;
}
if(summary.details.size()>0)
{
totalSummary.totVolume = totalSummary.totVolume + summary.totVolume;
totalSummary.totDuration = totalSummary.totDuration + summary.totDuration;
totalSummary.details.add(summary);
summary = new SensorSummaryDataOut();
}
totalSummary.avgVolume = totalSummary.totVolume/totalSummary.details.size();
totalSummary.deviceguid = deviceGuid;
String json = "";
Gson gson = new Gson();
json = gson.toJson(totalSummary);
return json;
} //End of Function
Upvotes: 0