I have a class Movie
in it i have a start Date, a duration and a stop Date.
Start and stop Date are Date Objects (private Date startDate ...)
(It's an assignment so i cant change that)
now I want to automatically calculate the stopDate by adding the duration (in min) to the startDate.
By my knowledge working with the time manipulating functions of Date is deprecated hence bad practice but on the other side i see no way to convert the Date object to a calendar object in order to manipulate the time and reconvert it to a Date object.
Is there a way? And if there is what would be best practice
What you could do is creating an instance of a GregorianCalendar and then set the Date as a start time:
Date date;
Calendar myCal = new GregorianCalendar();
myCal.setTime(date);
However, another approach is to not use Date at all. You could use an approach like this:
private Calendar startTime;
private long duration;
private long startNanos; //Nano-second precision, could be less precise
...
this.startTime = Calendar.getInstance();
this.duration = 0;
this.startNanos = System.nanoTime();
public void setEndTime() {
this.duration = System.nanoTime() - this.startNanos;
}
public Calendar getStartTime() {
return this.startTime;
}
public long getDuration() {
return this.duration;
}
In this way you can access both the start time and get the duration from start to stop. The precision is up to you of course.
Calendar tCalendar = Calendar.getInstance();
tCalendar.setTime(date);
date is a java.util.Date object. You may use Calendar.getInstance() as well to obtain the Calendar instance(much more efficient).
Calendar.setTime()
It's often useful to look at the signature and description of API methods, not just their name :) - Even in the Java standard API, names can sometimes be misleading.
You don't need to convert to Calendar for this, you can just use getTime()/setTime() instead.
getTime():
Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
setTime(long time) : Sets this Date object to represent a point in time that is time milliseconds after January 1, 1970 00:00:00 GMT. )
There are 1000 milliseconds in a second, and 60 seconds in a minute. Just do the math.
Date now = new Date();
Date oneMinuteInFuture = new Date(now.getTime() + 1000L * 60);
System.out.println(now);
System.out.println(oneMinuteInFuture);
The L suffix in 1000 signifies that it's a long literal; these calculations usually overflows int easily.
tl;dr
Instant stop =
myUtilDateStart.toInstant()
.plus( Duration.ofMinutes( x ) )
;
java.time
Other Answers are correct, especially the Answer by Borgwardt. But those Answers use outmoded legacy classes.
The original date-time classes bundled with Java have been supplanted with java.time classes. Perform your business logic in java.time types. Convert to the old types only where needed to work with old code not yet updated to handle java.time types.
If your Calendar is actually a GregorianCalendar you can convert to a ZonedDateTime. Find new methods added to the old classes to facilitate conversion to/from java.time types.
if( myUtilCalendar instanceof GregorianCalendar ) {
GregorianCalendar gregCal = (GregorianCalendar) myUtilCalendar; // Downcasting from the interface to the concrete class.
ZonedDateTime zdt = gregCal.toZonedDateTime(); // Create `ZonedDateTime` with same time zone info found in the `GregorianCalendar`
end if
If your Calendar is not a Gregorian, call toInstant to get an Instant object. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = myCal.toInstant();
Similarly, if starting with a java.util.Date object, convert to an 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 = myUtilDate.toInstant();
Apply a time zone to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
To get a java.util.Date object, go through the Instant.
java.util.Date utilDate = java.util.Date.from( zdt.toInstant() );
For more discussion of converting between the legacy date-time types and java.time, and a nifty diagram, see my Answer to another Question.
Duration
Represent the span of time as a Duration object. Your input for the duration is a number of minutes as mentioned in the Question.
Duration d = Duration.ofMinutes( yourMinutesGoHere );
You can add that to the start to determine the stop.
Instant stop = startInstant.plus( d );
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.
something like
movie.setStopDate(movie.getStartDate() + movie.getDurationInMinutes()* 60000);
Here is a full example on how to transform your date in different types:
Date date = Calendar.getInstance().getTime();
// Display a date in day, month, year format
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
String today = formatter.format(date);
System.out.println("Today : " + today);
// Display date with day name in a short format
formatter = new SimpleDateFormat("EEE, dd/MM/yyyy");
today = formatter.format(date);
System.out.println("Today : " + today);
// Display date with a short day and month name
formatter = new SimpleDateFormat("EEE, dd MMM yyyy");
today = formatter.format(date);
System.out.println("Today : " + today);
// Formatting date with full day and month name and show time up to
// milliseconds with AM/PM
formatter = new SimpleDateFormat("EEEE, dd MMMM yyyy, hh:mm:ss.SSS a");
today = formatter.format(date);
System.out.println("Today : " + today);
Extension for converting date to calendar in Kotlin.
fun Date?.toCalendar(): Calendar? {
return this?.let { date ->
val calendar = Calendar.getInstance()
calendar.time = date
calendar
}
}
Related
I am new to Java's Date class. When I try to use its getTime() function for calculating time difference, issues come out. For example, below is the code.
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
task = opt.get();
task.setEndDate(dateFormat.format(date));
Date startDate = null;
try {
startDate = dateFormat.parse(task.getStartDate());
} catch (ParseException e) {
System.out.println("date parsing error...");
startDate = date;
}
System.out.printf("Start date is: %s", task.getStartDate());
System.out.printf("Start date is: %d", startDate.getTime());
System.out.printf("End date is: %s", task.getEndDate());
System.out.printf("End date is: %d", date.getTime());
long diff = date.getTime() - startDate.getTime() - 43200000;
System.out.printf("Time difference is: %d", diff);
int secNum = (int)(diff / 1000);
String timeCost = String.valueOf(secNum);
System.out.println("Time cost(sec) is:");
System.out.println(timeCost);
task.setTimeCost(timeCost);
The outputs are:
Start date is: 2020-04-15 01:46:17
Start date is: 1586929577000
End date is: 2020-04-15 01:46:35
End date is: 1586972795461
Time difference is: 18461
Time cost(sec) is:18
As you might notice, there is 12 hours(43200000 ms) offset between the calculated difference and the real difference through "date.getTime() - startDate.getTime()".
I don't know what's going on.
Does anyone have an idea and correct me ?
It seems you are storing the date/time as a string in your task object, and converting between Date and String using the format "yyyy-MM-dd hh:mm:ss". I believe lower-case h means you are using a 12-hour clock, but you do not include an AM/PM indicator in your format string.
I'm guessing you ran the code at 1:46 PM to produce the sample output.
You have "2020-04-15 01:46:17" stored as your start date. When you convert that back to a date, the formatter doesn't know whether it is an AM time or PM time. I guess that it defaults to AM.
The Date object, however, knows that it was initialized with a PM time. Therefore, when you subtract the two, you get over 12 hours difference, because it is subtracting 1:46:17 AM from 1:46:35 PM.
A simple recommendation would be to add an AM/PM indicator to your date format, or use a 24-hour clock (upper-case H in the format string).
An even better recommendation would be to store dates as dates, not as strings! Convert them to strings when you want to display them.
You are using hh which is a 12-hour hour format, hence 20:00 becomes 08:00. You should use HH which is a 24-hour format. The below illustrates the difference.
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
Date date = new Date(1586973600000L);
System.out.println(date);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String fd1 = df.format(date);
System.out.println(fd1);
System.out.println(df.parse(fd1));
df.applyPattern("yyyy-MM-dd HH:mm:ss");
String fd2 = df.format(date);
System.out.println(fd2);
System.out.println(df.parse(fd2));
Also, java.util.Date is old, buggy and generally avoided for some time now. You might want to switch to java.time instead.
java.time
I am new to Java's Date class.
Stop! Backup, rewind.
Both java.util.Date and java.sql.Date classes are terrible, deeply flawed, and quite frustrating. Never use these classes.
These classes were shipped in the earliest versions of Java. Supplanted years ago by the modern java.time classes defined in JSR 310.
Date date = new Date();
To capture the current moment in UTC, use Instant.now. Uses a resolution finer than the milliseconds used in the java.util.Date class it replaced.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
task.setEndDate(dateFormat.format(date));
Your Task class should hold a java.time object rather than a mere string.
class Task {
Instant start , stop ;
…
}
Use smart objects rather than dumb strings throughout your Java codebase. Doing so ensures valid values, provides type-safety, and makes your code more self-documenting.
If your Task is like booking appointments in the future, where you want a certain time-of-day regardless of changes to the offset used by your time zone, then use LocalDateTime. This type represents only a date and time-of-day but lacks any concept of time zone or offset.
LocalDate ld = LocalDate.of( 2020 , Month.APRIL , 15 ) ;
Localtime lt = LocalTime.of( 15 , 30 ) ;
LocalDateTime ldt = LocalDateTime.of( ld , lt ) ;
When generating a calendar where you need a specific point on the timeline, then apply the relevant time zone.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
The issue at stake here is the fact that politicians around the world have shown a predilection for changing the offset used by the time zone(s) of their jurisdiction. The politicians do so with surprising frequency. And they have done so with little or no forewarning.
When exchanging date-time values with other systems textually, then use ISO 8601 formats. These formats are used by default in java.time when parsing/generating text. And for presentation to users, produce automatically localized strings using DateTimeFormatter.
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
This format is incorrect if you are trying to record moments, specific points on the timeline. You must include an indication of time zone and/or offset-from-UTC to track a moment.
For moments, use the ISO 8601 formats mentioned above. Used by default, so no need to specify a formatting pattern.
String input = "2020-01-23T01:23:45.123456789Z" ;
Instant instant = Instant.parse( input ) ;
Adjust from UTC into the wall-clock time used by the people of a particular region (a time zone).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Generate localized text.
Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( locale ) ;
String output = zdt.format( f ) ;
See this code run live at IdeOne.com.
zdt.toString(): 2020-01-22T20:23:45.123456789-05:00[America/Montreal]
output: mercredi 22 janvier 2020 à 20 h 23 min 45 s heure normale de l’Est
long diff = date.getTime() - startDate.getTime() - 43200000;
No need to do the math yourself. We have a class for that: Duration.
Duration d = Duration.between( start , stop ) ;
If you want a count of whole seconds across the entire span of time, call Duration::toSeconds.
long seconds = d.toSeconds() ; // Entire duration in terms of whole seconds.
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
So I have a string which is "2014-06-30 15:27" and if it is today's date it should only return "15:27" else "30/06/2014". I've already tried simpleDateFormat.parse but it didn't work very well.
holder.data.setText(mensagem.getDate());
final String stringDate = "2014-07-17 23:59";
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date date = inputFormat.parse(stringDate);
Calendar calendarDate = Calendar.getInstance();
calendarDate.setTime(date);
Calendar midnight = Calendar.getInstance();
midnight.set(Calendar.HOUR_OF_DAY, 0);
midnight.set(Calendar.MINUTE, 0);
midnight.set(Calendar.SECOND, 0);
midnight.set(Calendar.MILLISECOND, 0);
if (calendarDate.compareTo(midnight) >= 0)
{
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
System.out.println(timeFormat.format(date));
}
else
{
SimpleDateFormat dateTimeForm = new SimpleDateFormat("dd/MM/yyyy HH:mm");
System.out.println(dateTimeForm.format(date));
}
LocalDateTime
First parse the string as a LocalDateTime. Replace the SPACE in the middle with T to comply with standard ISO 8601 format. The java.time classes support ISO 8601 formats by default.
LocalDateTime ldt = LocalDateTime.parse ( "2014-06-30 15:27".replace ( " " , "T" ) );
ldt.toString(): 2014-06-30T15:27
Such a value has no real meaning. The input string lacked any clue about offset-from-UTC or time zone. So we do not know if this is 3 PM in Auckland NZ or 3 PM in Québec Canada, two very different moments. You should to assign the offset or time zone indicated by your business situation. Search Stack Overflow for how to do this, focussing on classes OffsetDateTime and ZonedDateTime. I'll skip over this crucial issue for now.
LocalDate
Extract a date-only value. The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate ld = ldt.toLocalDate();
Today
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
Comparison
You can compare LocalDate objects by calling methods such as compareTo, equals, isEqual, isBefore, isAfter.
if( today.isEqual( ld ) ) {
return ldt.toLocalTime();
} else {
return ld;
}
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 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?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
As the java.time library is the recommended way to use date and time. So, to compare current date with a string date you need to first convert date in string format to java.time.LocalDate :
LocalDate paresedStringDate = LocalDate.parse("2022-11-10");
After that you can get the current date using below code:
LocalDate currentDate = LocalDate.now();
And then you can compare both the current date and parsed string date to check if both are same using below code:
if (paresedStringDate.compareTo(currentDate) == 0) {
//do what you want to do here
}
Simply use the Date class...
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date exitdate = df.parse("2019-01-17");
Date currdate = new Date();
long diff = currdate.getTime() - exitdate.getTime();
long days = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
if(days==0)
{
System.out.println("IS TRUE"+currdate.toString());
return true;
}
I am in need to manipulate on java.sql.Timestamp.
Input to the function is:
Formatted DateTime in java.sql.Timestamp
[Possible date formats are: MM/dd/yyyy hh:mm:ss aa, MM/dd/yyyy hh:mm:ss, MM/dd/yyyy hh:mm aa, MM/dd/yyyy HH:mm, MM/dd/yy hh:mm aa, MM/dd/yy HH:mm, MM/dd/yyyy, and some others]
Required Output:
java.sql.Timestamp in another Timezone the same formatted DateTime as input
So basically I need to change timezone of the DateTime in java.sql.Timestamp
I have seen other posts, which mention to use JODA, but I can't use it due to some restrictions.
I have tried
- to convert java.sql.Timestamp to java.date.Calendar,
- then change the timezone,
- then convert to it to date
- format date to the same formatted datetime
See the code below:
Timestamp ts = "2012-06-20 18:22:42.0"; // I get this type of value from another function
Calendar cal = Calendar.getInstance();
cal.setTime(ts);
cal.add(Calendar.HOUR, -8);
String string = cal.getTime().toString(); // return value is in " DAY MMM dd hh:mm:ss PDT yyyy " format i.e. Wed Jun 20 10:22:42 PDT 2012
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss"); // This could be any format required
Date date;
try {
date = formatter.parse(string); // I am getting exception here on parsing
} catch (ParseException e1) {
e1.printStackTrace();
}
Can anyone tell me what is wrong here, or is there any other way to manipulate on Timezone for java.sql.Timestamp ?
Thanks.
You are misunderstanding and abusing these classes.
Timestamp & Date have no time zone but UTC
manipulate on Timezone for java.sql.Timestamp
A java.sql.Timestamp is always a moment in UTC. No other time zone is involved, only UTC. Ditto for java.util.Date – always in UTC, no other time zone involved.
So your Question, as quoted above, does not make sense.
Timestamp & Date have no “format”
Neither Timestamp nor Date have a “format”. They use their own internally defined way to track the date-time. They are not strings, so they have no format. You can generate a String to represent their value in a particular format, but such a String is distinct and separate from the generating object.
java.time
You are using troublesome old date-time classes that wore supplanted years ago by the java.time classes.
Both Timestamp and Date are replaced by 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).
Your input is
String input = "2012-06-20 18:22:42.0" ;
That input is nearly compliant with standard ISO 8601 format. To comply fully, replace the SPACE in the middle with a T.
String input = "2012-06-20 18:22:42.0".replace( " " , "T" ) ;
Parse as a LocalDateTime because it lacks an indicator of offset-from-UTC or time zone.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
A LocalDateTime, like your input string, does not represent a moment, is not a point on the timeline. Without the context of a time zone or offset-from-UTC, it has no real meaning. It represents only potential moments along a range of about 26-27 hours.
If you know the intended time zone, apply it to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
As for the other formats you mentioned, your Question is not at all clear. Search Stack Overflow for DateTimeFormatter class to see many examples and discussions of generating/parsing strings with the java.time classes. But first, get clear on the crucial concept that strings are not the date-time objects, and the date-time objects are not strings.
Database
If you were using java.sql.Timestamp to exchange data with a database, no need for that class anymore. As of JDBC 4.2 and later, you can directly exchange java.time objects with your database.
myPreparedStatement.setObject( … , instant ) ;
…and…
Instant instant = myResultSet.getObject( … , Instant.class ) ;
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 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?
Java SE 8, Java 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 Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
Think of Timestamp as being a fixed point in time, disconnected from where on earth you happen to be looking at a clock.
If you want to display what's on the calendar/clock for a person at that instant in a particular time zone, you can set a calendar to that time zone and then associate your SimpleDateFormat to that calendar.
For example:
public void testFormat() throws Exception {
Calendar pacific = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
Calendar atlantic = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Timestamp ts = new Timestamp(System.currentTimeMillis());
sdf.setCalendar(pacific);
System.out.println(sdf.format(ts));
sdf.setCalendar(atlantic);
System.out.println(sdf.format(ts));
}
My output was:
2012-06-25 20:27:12.506
2012-06-25 23:27:12.506
I got it solved, I am putting code for reference.
Timestamp ts = "2012-06-20 18:22:42.0"; // input date in Timestamp format
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Calendar cal = Calendar.getInstance();
cal.setTime(ts)
cal.add(Calendar.HOUR,-7); // Time different between UTC and PDT is -7 hours
String convertedCal = dateFormat.format(cal.getTime()); // This String is converted datetime
/* Now convert String formatted DateTime to Timestamp*/
SimpleDateFormat formatFrom = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
try {
Date date = formatFrom.parse(convertedCal);
Timestamp finalTS = new Timestamp(date.getTime()); // Final value in Timestamp: 2012-06-20 11:22:42.0
} catch (Exception e) {
e.printStackTrace();
}
Couldn't you simply:
Get original time in milliseconds
Convert timezone difference to milliseconds
Add or subtract the difference from the original time.
Create a new timestamp using the new time in milliseconds
you miss one argumment in formatter.parse
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html#parse(java.lang.String,%20java.text.ParsePosition)
I have seconds since 1970 january 1 UTC (Epoch time).
1320105600
I need to convert that seconds into date and time in below format.
Friday,November 4,2011 5:00,AM
How can I achieve this?
In case you're restricted to legacy java.util.Date and java.util.Calendar APIs, you need to take into account that the timestamps are interpreted in milliseconds, not seconds. So you first need to multiply it by 1000 to get the timestamp in milliseconds.
long seconds = 1320105600;
long millis = seconds * 1000;
This way you can feed it to a.o. the constructor of java.util.Date and finally use SimpleDateFormat to convert a java.util.Date to java.lang.String in the desired date format pattern, if necessary with a predefined time zone (otherwise it would use the system default time zone, which is not GMT/UTC per se and thus the formatted time might be off).
Date date = new Date(millis);
SimpleDateFormat sdf = new SimpleDateFormat("EEEE,MMMM d,yyyy h:mm,a", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String formattedDate = sdf.format(date);
System.out.println(formattedDate); // Tuesday,November 1,2011 12:00,AM
In case you're already on Java8, there's a LocalDateTime#ofEpochSecond() which allows you to feed epoch seconds directly without the need for multiplying into milliseconds flavor.
LocalDateTime dateTime = LocalDateTime.ofEpochSecond(seconds, 0, ZoneOffset.UTC);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE,MMMM d,yyyy h:mm,a", Locale.ENGLISH);
String formattedDate = dateTime.format(formatter);
System.out.println(formattedDate); // Tuesday,November 1,2011 12:00,AM
long yourSeconds = 1320105600L;
Date date = new Date(yourSeconds * 1000);
See this javadoc for more info. The constructor needs milliseconds.
To display this date in an appropriate format you should check DateFormat
Here is an example:
DateFormat df = new SimpleDateFormat("dd MMM yyyy hh:mm:ss zzz");
System.out.println(df.format(date));
java.time
The Answer by BalusC is good in that it points you to using java.time. But that Answer uses LocalDateTime where Instant is more appropriate. A LocalDateTime is not a moment on the timeline as it purposely has no concept of offset-from-UTC or time zone.
java.time
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat. The Joda-Time team also advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
Instant
A moment on the timeline in UTC with a resolution up to nanoseconds is represented by the Instant class.
Instant instant = Instant.ofEpochSecond ( 1_320_105_600L );
Dump to console. Your input value is the first moment of November 1, 2011 in UTC. The Z on the end, short for 'Zulu', means UTC.
System.out.println ( "instant: " + instant );
instant: 2011-11-01T00:00:00Z
ZonedDateTime
In your comments you mention wanting to see this date-time through the lens of the America/Chicago time zone. Use a proper time zone name. Apply a time zone, ZoneId, to get a ZonedDateTime object. We see that Chicago is five hours behind UTC on that date.
ZoneId zoneId = ZoneId.of ( "America/Chicago" );
ZonedDateTime zdt = instant.atZone ( zoneId );
zdt: 2011-10-31T19:00-05:00[America/Chicago]
Strings
The Strings seen above are in standard ISO 8601 format. To generate strings in other formats, use the DateTimeFormatter class. You can specify your own custom pattern. But generally best to let java.time automatically localize to the human language and cultural norms encoded in a Locale object.
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL );
formatter = formatter.withLocale ( Locale.US );
String output = zdt.format ( formatter );
Monday, October 31, 2011 7:00:00 PM CDT
To specify your own custom format, search Stack Overflow for many examples and more discussion.
int seconds = 1320105600;
Date date = new Date(seconds * 1000);
SimpleDateFormat sdf = new SimpleDateFormat("EEEE,MMMM d,yyyy h:mm,a");
System.out.println(sdf.format(date));
The trick is to use java.util.Date and java.text.DateFormat to get the format you want. You can look up how to do it in tutorials on the Web.
I have milliseconds in certain log file generated in server, I also know the locale from where the log file was generated, my problem is to convert milliseconds to date in specified format.
The processing of that log is happening on server located in different time zone. While converting to "SimpleDateFormat" program is taking date of the machine as such formatted date do not represent correct time of the server. Is there any way to handle this elegantly ?
long yourmilliseconds = 1322018752992l;
//1322018752992-Nov 22, 2011 9:25:52 PM
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS",Locale.US);
GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
calendar.setTimeInMillis(yourmilliseconds);
System.out.println("GregorianCalendar -"+sdf.format(calendar.getTime()));
DateTime jodaTime = new DateTime(yourmilliseconds,
DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSS");
System.out.println("jodaTime "+parser1.print(jodaTime));
Output:
Gregorian Calendar -2011-11-23 08:55:52,992
jodaTime 2011-11-22 21:25:52,992
You may use java.util.Date class and then use SimpleDateFormat to format the Date.
Date date=new Date(millis);
We can use java.time package (tutorial) - DateTime APIs introduced in the Java SE 8.
var instance = java.time.Instant.ofEpochMilli(millis);
var localDateTime = java.time.LocalDateTime
.ofInstant(instance, java.time.ZoneId.of("Asia/Kolkata"));
var zonedDateTime = java.time.ZonedDateTime
.ofInstant(instance,java.time.ZoneId.of("Asia/Kolkata"));
// Format the date
var formatter = java.time.format.DateTimeFormatter.ofPattern("u-M-d hh:mm:ss a O");
var string = zonedDateTime.format(formatter);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);
int mYear = calendar.get(Calendar.YEAR);
int mMonth = calendar.get(Calendar.MONTH);
int mDay = calendar.get(Calendar.DAY_OF_MONTH);
tl;dr
Instant.ofEpochMilli( 1_322_018_752_992L ) // Parse count of milliseconds-since-start-of-1970-UTC into an `Instant`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Assign a time zone to the `Instant` to produce a `ZonedDateTime` object.
Details
The other answers use outmoded or incorrect classes.
Avoid the old date-time classes such as java.util.Date/.Calendar. They have proven to be poorly designed, confusing, and troublesome.
java.time
The java.time framework comes built into Java 8 and later. Much of the functionality is backported to Java 6 & 7 and further adapted to Android. Made by the some of the same folks as had made Joda-Time.
An Instant is a moment on the timeline in UTC with a resolution of nanoseconds. Its epoch is first moment of 1970 in UTC.
Assuming your input data is a count of milliseconds from 1970-01-01T00:00:00Z (not clear in the Question), then we can easily instantiate an Instant.
Instant instant = Instant.ofEpochMilli( 1_322_018_752_992L );
instant.toString(): 2011-11-23T03:25:52.992Z
The Z in that standard ISO 8601 formatted string is short for Zulu and means UTC.
Apply a time zone using a proper time zone name, to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( zoneId );
See this code run live at IdeOne.com.
Asia/Kolkata time zone ?
I am guessing your are had an India time zone affecting your code. We see here that adjusting into Asia/Kolkata time zone renders the same time-of-day as you report, 08:55 which is five and a half hours ahead of our UTC value 03:25.
2011-11-23T08:55:52.992+05:30[Asia/Kolkata]
Default zone
You can apply the current default time zone of the JVM. Beware that the default can change at any moment during runtime. Any code in any thread of any app within the JVM can change the current default. If important, ask the user for their desired/expected time zone.
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
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 the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java 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 Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
The easiest way to do this is to use the Joda DateTime class and specify both the timestamp in milliseconds and the DateTimeZone you want.
I strongly recommend avoiding the built-in Java Date and Calendar classes; they're terrible.
If the millis value is number of millis since Jan 1, 1970 GMT, as is standard for the JVM, then that is independent of time zone. If you want to format it with a specific time zone, you can simply convert it to a GregorianCalendar object and set the timezone. After that there are numerous ways to format it.
My Solution
public class CalendarUtils {
public static String dateFormat = "dd-MM-yyyy hh:mm";
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
public static String ConvertMilliSecondsToFormattedDate(String milliSeconds){
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(Long.parseLong(milliSeconds));
return simpleDateFormat.format(calendar.getTime());
}
}
Easiest way:
private String millisToDate(long millis){
return DateFormat.getDateInstance(DateFormat.SHORT).format(millis);
//You can use DateFormat.LONG instead of SHORT
}
I do it like this:
static String formatDate(long dateInMillis) {
Date date = new Date(dateInMillis);
return DateFormat.getDateInstance().format(date);
}
You can also use getDateInstance(int style) with following parameters:
DateFormat.SHORT
DateFormat.MEDIUM
DateFormat.LONG
DateFormat.FULL
DateFormat.DEFAULT
The SimpleDateFormat class has a method called SetTimeZone(TimeZone) that is inherited from the DateFormat class. http://docs.oracle.com/javase/6/docs/api/java/text/DateFormat.html
You can try java.time api;
Instant date = Instant.ofEpochMilli(1549362600000l);
LocalDateTime utc = LocalDateTime.ofInstant(date, ZoneOffset.UTC);
Below is my solution to get date from miliseconds to date format. You have to use Joda Library to get this code run.
import java.util.GregorianCalendar;
import java.util.TimeZone;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class time {
public static void main(String args[]){
String str = "1431601084000";
long geTime= Long.parseLong(str);
GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
calendar.setTimeInMillis(geTime);
DateTime jodaTime = new DateTime(geTime,
DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd");
System.out.println("Get Time : "+parser1.print(jodaTime));
}
}
public static String getFormatTimeWithTZ(Date currentTime) {
SimpleDateFormat timeZoneDate = new SimpleDateFormat("EEE, dd-MM-yyyy hh:mm a", Locale.getDefault());
return timeZoneDate.format(currentTime);
}
Output is
Mon,01-03-2021 07:37 PM
and
public static String getFormatTimeWithTZ(Date currentTime) {
SimpleDateFormat timeZoneDate = new SimpleDateFormat("EEE, dd-MM-yyyy HH:mm ", Locale.getDefault());
return timeZoneDate.format(currentTime);
}
output is
Mon,01-03-2021 19:37
if you do not want the Days Then Remove EEE,
if you do not want the Date Then Remove dd-MM-yyyy
If you want Time in Hour, Minutes, Second, Millisecond then Use HH:mm:ss.SSS
and Call this method where you want
getFormatTimeWithTZ(Mydate)
where
Date Mydate = new Date(System.currentTimeMillis());
public static LocalDateTime timestampToLocalDateTime(Long timestamp) {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), TimeZone.getDefault().toZoneId());
}