How to round off the current timestamp in milliseconds to seconds?
If this is the current timestamp in milliseconds I have -
1384393612958
The if I am rounding off to nearest second then will it be like this?
Time in MS rounded off to nearest Second = 1384393612000
I might need to do this both in Java and C++.
If you are using Python:
old_number = 1384393612958
new_number = 1000 * (old_number / 1000)
print new_number
Basically you want to use an integer number, divide by one thousand (to shave off the milli-seconds), and then multiple by thousand to get the ms value rounded to seconds.
In Java you can use Calendar to something like this:
Calendar cal = Calendar.getInstance().setTimeInMillis(millisec);
int seconds = cal.get(Calendar.SECONDS);
Alternatively (and can work for C++ too) you can do:
int sec = ((millisec + 500) / 1000);
adding 500 ms allows you to round the number properly.
tl;dr
Instant.ofEpochMilli( 1_384_393_612_958L )
.truncatedTo( ChronoUnit.SECONDS )
.toEpochMilli()
java.time
The modern approach in Java uses the java.time classes.
The Instant class represents a point on the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.ofEpochMilli( 1_384_393_612_958L ) ;
Instant instantTrunc = instant.truncatedTo( ChronoUnit.SECONDS ) ;
long millis = instantTrunc.toEpochMilli() ;
This is needed to convert java date object to mysql datetime formatted string in sql queries.
Conversion:
Calendar cal = Calendar.getInstance();
cal.setTime(this.id.getCreatedOn());
if (cal.get(Calendar.MILLISECOND) >= 500 ) {
System.out.println("Round off milliseconds to seconds");
cal.set(Calendar.SECOND, cal.get(Calendar.SECOND) + 1);
}
Date roundedCreatedOn = cal.getTime();
Actual query string contains:
createdOn = '" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(roundedCreatedOn)+ "'"
In javascript, using the moment.js library:
moment(timestamp).startOf('second')
Related
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
}
This question already has answers here:
Calculating the difference between two Java date instances
(45 answers)
Closed 7 years ago.
Im trying to calculate the time difference between 2 Timestamps, this is the code:
Calendar calendar = Calendar.getInstance();
java.util.Date now = calendar.getTime();
Timestamp currentTimestamp = new Timestamp(now.getTime());
System.out.println("Current\n"+currentTimestamp);
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = dateFormat.parse("28/02/2015");
Timestamp timestampBefore = new Timestamp(date.getTime());
System.out.println("Before\n"+timestampBefore);
Timestamp calculated = new Timestamp(currentTimestamp.getTime() - timestampBefore.getTime());
System.out.println("Calculated\n"+calculated);
Output:
Current
2015-02-28 12:12:40.975
Before
2015-02-28 00:00:00.0
Calculated
1970-01-01 13:12:40.975
I can understand why it returns 1970-01-01 but why does it return 13:12:40.975 ,1 hour more?
How to calculate the difference between 2 dates so the output is like this (based on this example):
Years:0, Months:0, Days:0, Hours:12, Minutes:12, Seconds:40 ?
Update: for java below 1.8 check out http://www.joda.org/joda-time/index.html
and for java 1.8 see answer.
Similar solution here: Java 8: Calculate difference between two LocalDateTime
(1) A timestamp is a point in time. If you calculate the difference between two timestamps, the result is not a timestamp (point in time), but a duration. So it is nonsense to convert the difference to a timestamp, hence it is useless to discuss the reason why the result is strange.
(2) You should probably use the new Java 8 time API (if you are able to use Java 8):
LocalTime now = LocalTime.now();
LocalTime previous = LocalTime.of(0, 0, 0, 0);
Duration duration = Duration.between(previous, now);
System.out.println(now);
System.out.println(previous);
System.out.println(duration);
Note that this just calculates the duration between two times of a day (hour-minute-second). If your want to include date information, use LocalDateTime instead:
LocalDateTime nextFirework = LocalDate.now()
.with(TemporalAdjusters.firstDayOfNextYear())
.atTime(LocalTime.MIDNIGHT);
LocalDateTime now = LocalDateTime.now();
// duration (in seconds and nanos)
Duration duration = Duration.between(now, nextFirework);
// duration in total hours
long hours = now.until(nextFirework, ChronoUnit.HOURS);
// equals to: duration.toHours();
If you want to have 'normalized' duration in years/months/days/hours/seconds, there is suprisingly no direct support. You could convert the duration to days, hours, minutes and seconds by yourself:
long d = duration.toDays();
long h = duration.toHours() - 24 * d;
long m = duration.toMinutes() - 60 * duration.toHours();
long s = duration.getSeconds() - 60 * duration.toMinutes();
System.out.println(d + "d " + h + "h " + m + "m " + s + "s ");
But note that you will have difficulties converting the days into months and years, as there is no unique number of days per month and a year can be a leap year with 366 days. For that, you can use Period, as in opposite to Duration, this class is associated with a timeline. Unfortunately, Period does only support dates, but no times:
// period in years/months/days (ignoring time information)
Period p = Period.between(now.toLocalDate(), nextFirework.toLocalDate());
System.out.println(p); // or use p.getYears(), p.getMonths(), p.getDays()
So probably you could combine both approaches - first, compute the Period from the dates and then the Duration using the times. Note that the duration can be negative, so you'll have to take care of that in case of:
Duration dur = Duration.between(start.toLocalTime(), end.toLocalTime());
LocalDate e = end.toLocalDate();
if (dur.isNegative()) {
dur = dur.plusDays(1);
e = e.minusDays(1);
}
Period per = Period.between(start.toLocalDate(), e);
System.out.println(per.toString() + ", " + dur.toString());
I have some time Strings such as "09:00" and "17:30" and I need to check if the current time is between that range.
I thought I could make this comparison:
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
Date now = new Date();
Date begin;
Date end;
begin = format.parse(begin_string);
end = format.parse(end_string);
if (now.compareTo(begin) > 0 && end.compareTo(now) > 0)
return true;
else
return false;
Turns out that when I parse the strings, the times are parsed correctly, but the date is set to Jan 1st 1970. This way, the code will always return false.
I'd like to know how can I set begin and end to the current date, but with the times from their strings.
You could also just reuse your format object for current time like this way:
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
Date now = new Date();
String time = format.format(now); // format to wall time loosing current date
System.out.println(time);
now = format.parse(time); // reparse wall time
System.out.println(now);
So you transform now to 1970 using implicitly the standard time zone of your system and can then use it for direct comparisons with begin and end.
Date begin = format.parse("09:00");
Date end = format.parse("21:30");
return (begin.before(now) && end.after(now)); // open-bounded interval
Get current time, Calendar.getInstance();
Get another 2 instance of current time, and set time fields based on your input
For example:
Calendar.set(Calendar.HOUR_OF_DAY, 1);
and invoke compare() on the boundry of time
You should really use a Calendar. Then you can individually set the hours and minutes from values parsed from the string. Then get the time in milliseconds and compare those.
Date now = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(now);
cal.set(Calendar.HOUR_OF_DAY, hours);
cal.set(Calendar.MINUTE, minutes);
long time = cal.getTimeInMillis();
You could also use the wonderful Joda library. In my opinion Joda is a much better way to work with Dates and Times.
The bundled java.util.Date & .Calendar classes are notoriously troublesome. Avoid them. Use either Joda-Time library or the new java.time package found in Java 8 (inspired by Joda-Time, defined by JSR 310).
If you truly do not care about time zone or date, use either the Joda-Time LocalTime class or the java.time LocalTime class.
Caution: Naïve programmers often think they need only local time and can therefore ignore time zones, but then live to regret that position.
Joda-Time
If your times are in proper ISO 8601 format (24-hours, correct number of digits), then you can directly pass the string inputs to the constructor of LocalTime without bothering to parse. That class has a built-in ISO 8601 style parser.
String inputStart = "09:00";
String inputStop = "17:30";
LocalTime start = new LocalTime( inputStart );
LocalTime stop = new LocalTime( inputStop );
LocalTime now = LocalTime.now();
// Comparing using Half-Open logic, where beginning is inclusive and ending is exclusive.
boolean isNowContainedWithinInterval = ( ( now.isEqual( start ) ) || ( now.isAfter( start ) ) ) && ( now.isBefore( stop ) );
Dump to console…
System.out.println( "start: " + start );
System.out.println( "stop: " + stop );
System.out.println( "now: " + now );
System.out.println( "isNowContainedWithinInterval: " + isNowContainedWithinInterval );
When run…
start: 09:00:00.000
stop: 17:30:00.000
now: 12:42:06.567
isNowContainedWithinInterval: true
In the real-world, I would add an assertion test proving the stop time is later than the start time, to validate inputs.
I want convert the Date in long. But the hours are incorrectly calculated at pc. On Android emulator is the Time correct calculated(on emulator is UTC time). Please help
String time = "15:54";
Date date = new Date();
date.setHours(Integer.parseInt(time.substring(0, 2)));
long Hours = (date.getTime() / (1000 * 60 * 60)) % 24;
System.out.print(Hours); // 14
System.out.print("\n" + date.getHours()); // 15
When you are setting the hours to Date, java.util.Date object is independent of the concept of TimeZone. Per its javadoc here,
Although the Date class is intended to reflect coordinated universal
time (UTC), it may not do so exactly, depending on the host
environment of the Java Virtual Machine.
Hence, when you set your hours to 15, date interprets your own timezone and sets the hours to it. If there is a difference in UTC (the result you expect) and your current timezone, that difference is being reflected in your case above (14 vs 15).
To solve it, 1 option is to explicitly bring your own timezone to UTC and match the expected results:
String time = "15:54";
Date date = new Date();
java.util.TimeZone.setDefault(TimeZone.getTimeZone("UTC")); // ADDED THIS LINE
date.setHours(Integer.parseInt(time.substring(0, 2)));
long hours = (date.getTime() / (60 * 60 * 1000)) % 24;
System.out.print(hours); // NOW THIS GIVES 15
System.out.print("\n" + date.getHours()); // 15
The other option would to use Calendar class (if not jodatime) in case you want to accurately interpret the TimeZone related results.
Your question is not clear.
This kind of date-time work is much easier with the Joda-Time library.
Relying on the default time zone is troublesome. Instead, specify your time zone. It sounds like in your case the desired hour "15" is in UTC/GMT (no time zone offset). So, specify UTC.
What did you mean by "convert the Date in long"? Perhaps you meant get the milliseconds-since-epoch stored inside the Date (and in Joda-Time DateTime).
DateTime now = new DateTime( DateTimeZone.UTC );
DateTime fifteen = now.withHourOfDay( 15 );
Dump to console…
System.out.println( "now: " + now );
System.out.println( "fifteen: " + fifteen );
System.out.println( "fifteen in millis: " + fifteen.getMillis() );
System.out.println( "fifteen's hour-of-day: " + fifteen.getHourOfDay() );
When run…
now: 2014-02-14T12:43:00.836Z
fifteen: 2014-02-14T15:43:00.836Z
fifteen in millis: 1392392580836
fifteen's hour-of-day: 15
If try to call method:
private static String TIME_FORMAT = "HH:mm Z";
public static void TestDate( String time_ ) throws ParseException
{
SimpleDateFormat format = new SimpleDateFormat( TIME_FORMAT );
Date date = format.parse( time_ );
long hours = (date.getTime() / (1000 * 60 * 60)) % 24;
System.out.println( "The value 'hours' for '" + time_ + "' is '" + Long.toString( hours ) + "'" );
}
with "15:54 UTC", output wil be:
The value 'hours' for '15:54 UTC' is '15'
So my method receives a time in 24 hour format ("HH:MM:SS") and returns a string the difference time. If it's 2:00PM local time I should be able to send it "16:30:00"(4:30PM) and get the output "2 hours, 30 mins". But the code has some problem, and I am just a beginner and I need help to fix it.
The problem is if the time is 4:40PM, and I sent it "17:00:00"(5:00PM) it returns the message:
12 hours, 20 minutes instead of 0 hours, 20 minutes.
The other problem is if I sent it the current time, it would return "12 hours" away, and not 24 like it should.
Please keep in mind I am only a beginner at java and math really isn't my thing, so any help is highly appreciated. Thanks.
private static String timeUntil(String distanceTime) {
String returnMsg = null;
try {
SimpleDateFormat sdfDate = new SimpleDateFormat("hh:mm:ss");
Date now = new Date();
java.text.DateFormat df = new java.text.SimpleDateFormat("hh:mm:ss");
Date date1 = df.parse(sdfDate.format(now));
Date date2 = df.parse(distanceTime);
long diff = date2.getTime() - date1.getTime();
int timeInSeconds = (int) (diff / 1000);
int hours, minutes;
hours = timeInSeconds / 3600;
timeInSeconds = timeInSeconds - (hours * 3600);
minutes = timeInSeconds / 60;
if (hours >= 0) {
returnMsg = hours + " hours" +
"\n" + minutes + " mins";
} else {
returnMsg = minutes + " mins";
}
} catch (Exception e) {
e.printStackTrace();
}
return returnMsg;
}
In your date format, hh is used for 12-hour time. Use HH for 24-hour time:
new SimpleDateFormat("HH:mm:ss");
Code review comments...
Most of the Date class' methods are deprecated. You should consider using Calendar (GregorianCalendar) instead of Date.
Your variable names often lack meaning - you have to know the purpose of the variable to know its meaning. Your code will be more maintainable if you use better variable names. df could be renamed "format" or "dateFormat".
You create a Date object 'now', then you pass it through your df DateFormat instance, hten through your sdfDate instance, to convert it back to a Date. This is unnecessary. Replace this with Date date1 = new Date(); and remove Date now = new Date();. Simiilarly, I've seen very difficult to diagnose errors when converting between units, so you should change diff to indicate that it's milliseconds, like diff_ms. And you should keep names consistent - you change from "different" (diff) to "timeInSeconds". They should both be "timeInXxx" or "diff_xx". the distanceTime parameter should be renamed something like futureTime
You do a bunch of math to determine the difference between two times, but there are libraries that will do this for you. Google for "java difference between two dates" and find many answers.
Your code always assumes that the second time occurs after "now". This should be included in a comment at the top of your method.
When you instantiate date1 and date2, they're both probably for the same day. Try debugging or at least printing the objects to stdout immediately after they're created to see if this is the case. Is this what you really want?
Your code doesn't handle leap year.
Instead of handling all of the time conversions yourself, why don't you look for a library that does it for you?
This is your fixed code. I have changed the date format to HH:mm:ss and also your calculation logic. Try it and let us know
private static String timeUntil(String distanceTime) {
String returnMsg = null;
try {
SimpleDateFormat sdfDate = new SimpleDateFormat("HH:mm:ss");
Date now = new Date();
java.text.DateFormat df = new java.text.SimpleDateFormat("HH:mm:ss");
Date date1 = df.parse(sdfDate.format(now));
Date date2 = df.parse(distanceTime);
long diff = date2.getTime() - date1.getTime();
int timeInSeconds = (int) (diff / 1000);
int hours, minutes;
hours = timeInSeconds / 3600;
timeInSeconds = timeInSeconds - (hours * 3600);
minutes = timeInSeconds / 60;
if (hours != 0) {
returnMsg = hours + " hours" +
"\n" + minutes + " mins";
} else {
returnMsg = minutes + " mins";
}
} catch (Exception e) {
e.printStackTrace();
}
return returnMsg;
}
Here is an example which is more robust and uses Java more modern date functions. I could go point by point and point at all the thing you could have done better in your example, but sometimes its easier to give you a good example and let you glean what you can from other people code as far as good style.
import java.util.Calendar;
public class testSpace {
public static void main (String ... args){
System.out.println(timeUntil("00:12:12"));
}
private static String timeUntil(String distanceTime){
String[] times = distanceTime.split(":");
Calendar now = Calendar.getInstance();
Calendar then = Calendar.getInstance();
then.set(Calendar.SECOND, Integer.parseInt(times[2]));
then.set(Calendar.MINUTE, Integer.parseInt(times[1]));
then.set(Calendar.HOUR, Integer.parseInt(times[0]) % 12);
then.set(Calendar.AM_PM, (Integer.parseInt(times[0]) >= 12 ) ? Calendar.PM : Calendar.AM);
boolean isFuture = (then.getTimeInMillis() > now.getTimeInMillis());
long interval = (isFuture)
? then.getTimeInMillis() - now.getTimeInMillis()
: now.getTimeInMillis() - then.getTimeInMillis();
return ((isFuture) ? "" : "-") + millToTime(interval);
}
public static long MILLISECOND_PER_HOUR = 1000*60*60;
public static long MILLISECOND_PER_MIN = 1000*60;
public static long MILLISECOND_PER_SECOND = 1000;
public static String millToTime(long mill){
long hours = mill / MILLISECOND_PER_HOUR;
long mins = (mill % MILLISECOND_PER_HOUR) / MILLISECOND_PER_MIN;
long sec = ((mill % MILLISECOND_PER_HOUR) % MILLISECOND_PER_MIN) / MILLISECOND_PER_SECOND;
return String.format("%d:%d:%d", hours, mins, sec);
}
}
tl;dr
For time-of-day only, without a date or time zone.
LocalTime start = LocalTime.of( "16:40" ) ;
LocalTime stop = LocalTime.of( "17:00" ) ;
Duration d = Duration.between( start , stop ) ;
PT20M
Or, for date-time in a zone.
ZoneId z = ZoneId.of( "America/Montreal" )
ZonedDateTime zdtNow = ZonedDateTime.now( z );
ZonedDateTime zdtThen =
ZonedDateTime.of( // Pass a LocalDate, LocalTime, ZoneId.
zdtNow.toLocalDate() , // Same date…
LocalTime.parse( "16:30:00" ) , // … but different time-of-day.
z
)
Duration d = Duration.between( zdtNow , zdtThen ) ;
PT2H30M
Details
You are using old date-time classes, now legacy, supplanted by the java.time classes.
LocalTime
You are incorrectly using a date-time class for a time-of-day-only value. Instead use the LocalTime class. And use a span-of-time class when calculating elapsed time.
String input = "16:30:00" ;
LocalTime lt = LocalTime.parse( input );
Instant
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now();
ZonedDateTime
Determining a wall-clock time requires a time zone. Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtNow = instant.atZone( z ); // Adjusted into your time zone.
Now construct a ZonedDateTime for your given input time-of-day.
ZonedDateTime zdtTarget = ZonedDateTime.of( zdtNow.toLocalDate() , lt , z );
Duration
Use Duration to represent elapsed time not attached to the timeline.
Duration d = Duration.between( zdtNow , zdtTarget );
Note that the duration will be a negative amount if the specified time-of-day is earlier than the current time-of-day.
ISO 8601 string for duration
To get a String describing the hours, minutes, etc. of that span of time, simply call toString to generate a String in standard ISO 8601 format of PnYnMnDTnHnMnS where P marks the beginning and T separates the years-month-days from hours-minutes-seconds.
If the current time were 14:00:00 in the same zone, the output would be:
PT2H30M
Getter methods
Oddly, in Java 8 this class Duration lacks any getter methods for the parts such as 2 for hours and 30 for minutes. Remedied in Java 9 with methods such as toHoursPart and toMinutesPart.
About java.time
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 java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
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.