I am using Java 8. In one of my web service I am getting the date format like this: 2017-10-17T04:11:51+00:00.
I would like to test if the timestamp is 20 minutes ago. For this I've written below code but it's not working:
Long minutesAgo = new Long(20);
String lastDate = "2017-10-17T04:11:51+00:00";
OffsetDateTime odt = OffsetDateTime.parse(lastDate);
Instant instant = odt.toInstant(); // Instant is always in UTC.
java.util.Date date = java.util.Date.from( instant );
Date dateIn_X_MinAgo = new Date (date.getTime() - minutesAgo*60*1000);
System.out.println(dateIn_X_MinAgo.getTime()); //It prints 1508212311000
Could somebody take a look at my code?
You're using the new java.time API (OffsetDateTime and Instant), so there's no need to mix it with the old java.util.Date class.
You can use a java.time.temporal.ChronoUnit to get the difference between 2 instants in minutes, and Instant.now() to get the current instant:
String lastDate = "2017-10-17T04:11:51+00:00";
OffsetDateTime odt = OffsetDateTime.parse(lastDate);
// get difference from now (in minutes)
long diff = ChronoUnit.MINUTES.between(odt.toInstant(), Instant.now());
if (diff > 20) {
// odt is more than 20 minutes ago
}
Related
I'm trying to convert a Brazil local date to UTC format. I have developed my solution but I'm sure that it can be improved. I have been searching for others questions but without success.
My problem is that when I process the Date object with:
Instant endDateTime = questionDate.toInstant();
I receive a UTC date as "2017-11-16T00:00:00Z" but this should be Brazil local date (not correct because it has a trailing "Z") and when I try to convert to UTC, I receive the same output.
In another hand, if I use ZoneDateTime class and build the date with LocalDateTime object I lose the seconds in the output: "2017-11-16T02:00Z". This happens when I use:
LocalTime.of(hour, minutes, seconds);
I search into LocalTime class and I think this is because minutes or seconds are 0 but I'm not sure of it.
Problems of the solution:
The response hasn't seconds
I hope Java 8 has a set of functions to make this more simple and clear
Precondition:
I can't use Joda library
Result has to be OffsetDateTime class
Input: Date "2017-11-16"
Output: "2017-11-16T02:00:00Z"
This is my solution:
private static OffsetDateTime processDate(Date questionDate) {
Instant endDateTime = questionDate.toInstant();
ZoneId zoneId = ZoneId.of(ZONEID);
String [] date = endDateTime.toString().split("T");
LocalDateTime localDateTime = convertLocalTimeToUtc(date);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zoneId);
ZonedDateTime utcDate = zonedDateTime.withZoneSameInstant(ZoneOffset.UTC);
return utcDate.toOffsetDateTime();
}
private static LocalDateTime convertLocalTimeToUtc(String[] dateFromCountry) {
LocalDate date = processDate(dateFromCountry[0]);
LocalTime time = processTime(dateFromCountry[1]);
return LocalDateTime.of(date, time);
}
private static LocalDate processDate(String dateFromCountry) {
String [] partsOfDate = dateFromCountry.split("-");
int year = Integer.parseInt(partsOfDate[0]);
int month = Integer.parseInt(partsOfDate[1]);
int day = Integer.parseInt(partsOfDate[2]);
return LocalDate.of(year, month, day);
}
private static LocalTime processTime(String dateFromCountry) {
String [] partsOfTime = dateFromCountry.split(":");
int hour = Integer.parseInt(partsOfTime[0]);
int minutes = Integer.parseInt(partsOfTime[1]);
int seconds = Integer.parseInt(partsOfTime[2].substring(0,1));
return LocalTime.of(hour,minutes,seconds);
}
If your input is a java.util.Date, you can get rid of all the string manipulation:
//simulate your input
Instant input = Instant.parse("2017-11-16T00:00:00Z");
Date d = Date.from(input);
//transformation code starts here
Instant instant = d.toInstant();
ZonedDateTime localInstant = instant.atZone(ZoneOffset.UTC);
ZonedDateTime sameLocalInBrazil = utcInstant.withZoneSameLocal(ZoneId.of("Brazil/East"));
OffsetDateTime sameInstantUtc = sameLocalInBrazil.toOffsetDateTime()
.withOffsetSameInstant(ZoneOffset.UTC);
This return an OffsetDateTime with value 2017-11-16T02:00Z as you expect.
Note that an OffsetDateTime has no formatting - so the object does know that its seconds are set to 0 but the default toString method doesn't print them. If you want to print it with seconds, you can use a formatter:
//Formatting
System.out.println(sameInstantUtc.format(DateTimeFormatter.ISO_INSTANT));
which prints 2017-11-16T02:00:00Z
If your input is a java.sql.Date, you can use a slightly different strategy:
LocalDate d = sqlDate.toLocalDate();
ZonedDateTime localInstant = d.atStartOfDay(ZoneOffset.UTC);
The rest of the code would be the same.
I'm trying to create a simple Alarm Clock, but I stumbled upon a problem that I can't seem to fix. I'm trying to parse a string to a date so I can get the difference between the current time and the time to set off the alarm.
Here's my code to parse the time:
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
sdf.setTimeZone(getTimezone());
Date date = sdf.parse(args[0]);
Here's my getTimezone() method:
public static TimeZone getTimezone() {
Calendar cal = Calendar.getInstance();
long milliDiff = cal.get(Calendar.ZONE_OFFSET);
String [] ids = TimeZone.getAvailableIDs();
String name = null;
for (String id : ids) {
TimeZone tz = TimeZone.getTimeZone(id);
if (tz.getRawOffset() == milliDiff) {
// Found a match.
name = id;
break;
}
}
return TimeZone.getTimeZone(name);
}
And here's my code for figuring out the difference:
long diff = date.getTime() - System.currentTimeMillis();
So my problem is that the date.getTime() returns 79680000, while System.currentTimeMillis() returns 1473538047978 (This is of course different every time, but for some odd reason, date.getTime() is not).
Which means that I get a negative number when trying to figure out the difference, and therefore I cannot use it.
EDIT: After a little bit of debugging, I realised that it has to do with the year, month and day not being set, however I do not know how to get those.
You did notice that date.getTime() returns 79680000 which is 22 hours and 20 minutes after 1 January 1970. The problem is (as you noticed) that you did not parse year, month and day.
You can do it by:
SimpleDateFormat sdf = new SimpleDateFormat("DD/MM/YYYY hh:mm:ss");
Example input 20/04/2016 20:20:0 returns time as Mon Jan 04 20:20:00 CET 2016 (don't look at the timezone). It is 1451935200000 miliseconds after 1 January 1970.
Note: change string to match your format requirements (the syntax is self-explanatory).
The accepted answer by Ronin is correct. You are trying to put a time-of-day value into a date-time type.
java.time
Also, you are using troublesome old legacy date-time classes. Now supplanted by the java.time classes.
For a time-of-day value without a date and without a time zone, use LocalTime.
LocalTime alarmTime = LocalTime.parse( "12:34" );
Getting current time-of-day requires a time zone.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalTime now = LocalTime.now( z );
But since we are setting an alarm, we care about the date too.
ZonedDateTime now = ZonedDateTime.now( z );
ZonedDateTime alarm = null;
if ( now.toLocalTime().isBefore( alarmTime ) ) {
alarm = ZonedDateTime.of( now.toLocalDate() , alarmTime , z );
} else {. // Else too late for today, so set alarm for tomorrow.
alarm = ZonedDateTime.of( now.toLocalDate().plusDays( 1 ) , alarmTime , z );
}
To calculate the elapsed time until the alarm, use the Duration class.
Duration untilAlarm = Duration.between( now , alarm );
You can interrogate the duration for a total number of milliseconds. But know that java.time classes are capable of handling nanoseconds.
long millis = untilAlarm.toMillis();
Updated.
You are using only time without a date with you date object in code (parses only time). If you add there date to you time, your date should be comparable to your System.getCurrentTimeMillis() call. And if you subtracting current millis from date in the past, you will have negative numbers. I prefer this convertion (date2 is after date1):
long diffInMillies = date2.getTime() - date1.getTime();
return TimeUnit.convert(diffInMillies, TimeUnit.MILLISECONDS);
I must convert a linux timestamp to android date.
i get this number from server
1386889262
I have written a small code snippet.
Date d = new Date(jsonProductData.getLong(MTIME));
SimpleDateFormat f = new SimpleDateFormat("dd.MM.yyyy");
.setTimeZone(TimeZone.getTimeZone("GMT"));
formatTime = f.format(d);
but it doesen't convert right, this is my result
17.01.1970
EDIT:
Normally i must get this here
12.12.2013
Is there an another method to get the right date???
if your UNIX time stamp is of 10 digit then it does not include milliseconds so do this first 1386889262*1000
and if its 13 digit then it includes milliseconds also then you do not have to multiply unix timestamp with 1000.
In Kotlin we can use this function:
val unix=1386889262*1000 /*if time stamp is of 10 digit*/
val dateFormat = SimpleDateFormat("dd-MM-yy HH:mm:ss");
val dt = Date(unix);
textview.settext(dateFormat.format(dt))
UNIX timestamp should be in milliseconds so multiply the Long value by 1000. So your value 1386889262 would be 1386889262000:
tl;dr
Instant.ofEpochSecond( 1386889262L )
.atZone( ZoneId.of( "Pacific/Auckland" ) )
.toLocalDate()
.toString()
java.time
You appear to have a count of whole seconds from the epoch reference date of first moment of 1970 in UTC, 1970-01-01T00:00:00Z.
The modern approach uses the java.time classes that supplant the troublesome old date-time classes bundled with the earliest versions of Java. For older Android see the ThreeTen-Backport and ThreeTenABP projects.
An Instant represents a point on the timeline in UTC with a resolution of nanoseconds (up to nine digits of decimal fraction).
Instant instant = Instant.ofEpochSecond( 1386889262L ) ;
To generate a String representing this moment, call toString.
String output = instant.toString() ;
Determining a date requires a time zone. For any given moment, the date varies around the globe by zone. Assign a ZoneId to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Extract a date-only value for your purposes.
LocalDate ld = zdt.toLocalDate() ;
Generate a String.
String output = ld.toString() ;
For other formats in your String, search Stack Overflow for DateTimeFormatter.
Your timestamp or epoch time seems in sec "1386889262". You have to do something like this:
long date1 = 1386889262*1000;
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy HH:mm");
Date dt = new Date(date1);
datedisplay.setText(dateFormat.format(dt));
You can also get timestamp in java via
new Date().getTime() ;
It returns a long value.
EDIT: I have edited my question to include more information, I have tried many ways to do this already, asking a question on StackOverflow is usually my last resort. Any help is greatly appreciated.
I have a date (which is a Timestamp object) in a format of YYYYMMDDHHMMSS (e.g. 20140430193247). This is sent from my services to the front end which displays it in the format: date:'dd/MM/yyyy' using AngularJS.
How can I convert this into Epoch/Unix time?
I have tried the duplicate question that is linked to this, what I get returned is a different date.
I have also tried the following:
A:
//_time == 20140430193247
return _time.getTime()/1000; // returns 20140430193 - INCORRECT
B:
return _time.getTime(); // returns 20140430193247 (Frontend: 23/03/2608) - INCORRECT
C:
Date date = new Date();
//_time = 20140501143245 (i.e. 05/01/2014 14:32:45)
String str = _time.toString();
System.out.println("Time string is " + str);
//Prints: Time string is 2608-03-24 15:39:03.245 meaning _time.toString() cannot be used
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
try {
date = df.parse(str);
} catch (ParseException e) {
}
return date; // returns 20140501143245 - INCORRECT
D:
date = new java.sql.Date(_time.getTime());
return date; // returns 2608-03-24 - INCORRECT
The following shows the todays date correctly:
Date date = new Date();
return date; // returns 1398939384523 (Frontend: 01/05/2014)
Thanks
I got the answer after quite a while of trying different ways. The solution was pretty simple - to parse the time to a string as toString() didn't work.
Date date;
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
try {
date = df.parse(String.valueOf(_time.getTime()));
} catch (ParseException e) {
throw new RuntimeException("Failed to parse date: ", e);
}
return date.getTime();
tl;dr
LocalDateTime
.parse(
"20140430193247" ,
DateTimeFormatter.ofPattern( "uuuuMMddHHmmss" )
)
.atOffset(
ZoneOffset.UTC
)
.toEpochSecond()
java.time
Parse your input string as a LocalDateTime as it lacks an indicator of offset-from-UTC or time zone.
String input = "20140430193247" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMddHHmmss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
Now we have a date with time-of-day, around half-past 7 PM on April 30 of 2014. But we lack the context of offset/zone. So we do not know if this was 7 PM in Tokyo Japan or 7 PM in Toledo Ohio US, two different moments that happened several hours apart.
To determine a moment, you must know the intended offset/zone.
If you know for certain that an offset of zero, or UTC itself, was intended, apply the constant ZoneOffset.UTC to get an OffsetDateTime.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
How can I convert this into Epoch/Unix time?
Do you mean a count of seconds or milliseconds since the first moment of 1970 in UTC?
For a count of whole seconds since 1970-01-01T00:00Z, interrogate the OffsetDateTime object.
long secondsSinceEpoch = odt.toEpochSecond() ;
For milliseconds, extract a Instant object. An Instant represents a moment in UTC, and is the basic building-block class of java.time. Then interrogate for the count.
Instant instant = odt.toInstant() ;
long millisSinceEpoch = instant.toEpochMilli() ;
This question already has answers here:
Java 8 Date and Time: parse ISO 8601 string without colon in offset [duplicate]
(4 answers)
Closed 3 years ago.
StrDate = "2011-07-19T18:23:20+0000";
How can I get an epoch time for the above date format in android
also I would like to know how to convert a epoch time to the above date format.
I would appreciate a direct answer with an example.
Example code using Joda-Time 2.3.
Unix time is number of seconds since beginning of 1970 in UTC/GMT.
How can I get an epoch time for the above date format in android
DateTime dateTimeInUtc = new DateTime( "2011-07-19T18:23:20+0000", DateTimeZone.UTC );
long secondsSinceUnixEpoch = ( dateTimeInUtc.getMillis() / 1000 ); // Convert milliseconds to seconds.
…and…
how to convert a epoch time to the above date format.
String dateTimeAsString = new DateTime( secondsSinceUnixEpoch * 1000, DateTimeZone.UTC ).toString();
To dump those values to the console…
System.out.println( "dateTimeInUtc: " + dateTimeInUtc );
System.out.println( "secondsSinceUnixEpoch: " + secondsSinceUnixEpoch );
System.out.println( "dateTimeAsString: " + dateTimeAsString );
Bonus: Adjust to another time zone.
DateTime dateTimeMontréal = dateTimeInUtc.withZone( DateTimeZone.forID( "America/Montreal" ) );
You should use SimpleDateFormat. That class both supports formatting, and parsing.
Sample code:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZZZZ");
Date gmt = formatter.parse("2011-07-19T18:23:20+0000");
long millisecondsSinceEpoch0 = gmt.getTime();
String asString = formatter.format(gmt);
Note that a Date instance in Java, always represent milliseconds since epoch 0, in UTC/GMT, but it is printed in local time when you print it.
To answer your question a bit late but Joda-Time will be able to handle both in a simply and clean way.
Using Joda-Time
1.Epoch time to Date
Where date is your epoch time
DateTime dateTime = new DateTime(date*1000L);
System.out.println("Datetime ..." + dateTime);
Datetime from Epoch ...2014-08-01T13:00:00.000-04:00
2.Date to epoch
DateTime fromDate = new DateTime("2011-07-19T18:23:20+0000");
long epochTime = fromDate.getMillis();
System.out.println("Date is.." + fromDate + " epoch of date " + epochTime);
Date is..2011-07-19T14:23:20.000-04:00 epoch of date 1311099800000