I store a number of rows in DB with the timestamp of that moment in milliseconds.
Now if I need to retrieve all rows of a given day, like today, how do I correctly create the starting and ending milliseconds of that day?
I know about SimpleDateFormat and Calendar.getInstance() briefly, but would I need to do string manipulation (which I want to avoid) to get todays date only, add the hours part and then convert it back into milliseconds, or is there a better way to do it?
Since you didn't provide any code in your question, please allow me to give you a general answer in response..
What you're looking for are two date/times, today and tomorrow, both specified a "0 hours, 0 minutes, 0 seconds".
today <= date AND date < tomorrow
Note the two different comparisons.
The simplest technique would be to use DateFormat:
String input = "Sat Feb 17 2013";
Date date = new SimpleDateFormat("EEE MMM dd yyyy", Locale.ENGLISH).parse(input);
long milliseconds = date.getTime();
String input1="Sun Feb 18 2013"
Date inputNextDay = new SimpleDateFormat("EEE MMM dd yyyy", Locale.ENGLISH).parse(input);
long millisecondsForNextDay=inputNextDay.getTime();
To get the rows that fall on a particular day, just find rows having milliseconds value of timestamp between milliseconds and millisecondsForNextDay:
if(rowsTimestampSeconds>milliseconds && rowsTimestampSeconds<millisecondsForNextDay){
//get the row
}
You can use the GregorianCalendar class to do this without any strings.
Calendar calendar = new GregorianCalendar(year, month, day);
long start_of_day_millis = calendar.getTimeInMillis();
calendar.add(Calendar.DAY_OF_MONTH, 1);
long next_day_millis = calendar.getTimeInMillis();
The reason to use calendar.add(Calendar.DAY_OF_MONTH); instead of just adding (24*60*60*1000) to the first millisecond value is to account for leaps. Beyond the commonly known leap year, there are occurrences of leap seconds. See this link: http://www.timeanddate.com/time/leapseconds.html
Make sure that your expression is inclusive of start_of_day_millis (greater than or equal) and exlusive of next_day_millis (lesser than).
i.e: if(test_time >= start_of_day_millis && test_time < next_day_millis)
Update:
If you want today's date you can omit all the parameters in the calendar constructor and just call new GregorianCalendar(), but you will need to ensure that the hour, minute, second and millisecond fields are being zeroed out with calls to calendar.set(Calendar._FIELD_NAME_, 0); afterwards, before you use the calendar, because it would be initialized to the exact moment the object is created.
You should be using a date-time type for your database column to store date-time data rather than an integer of milliseconds. The SQL standard defines a few date-time types. But support for date-time varies widely, with Postgres being one of the best.
Since you tagged Java, read this Question and my Answer to learn about using Java to pinpoint the first moment of today and tomorrow. The Half-Open approach used there is common in date-time work. Half-Open means a span of time where the beginning is inclusive while the ending is exclusive. For SQL, it means not using the BETWEEN operator.
java.time
The java.time framework is built into Java 8 and later, and back-ported to Java 6 & 7 and to Android. Read my other Answer for details.
Get the first moments of today and tomorrow. Be aware that time zone is crucial in determining dates and the meaning of “today”. For any given moment, the date varies around the world by time zone. A new day begins earlier in the east. For example, a few moments after midnight in Paris is still “yesterday” in Montréal.
Instant instant = Instant.now();
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime zdtStart = zdt.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime zdtTomorrowStart = zdtStart.plusDays( 1 );
Some day we may see JDBC drivers updated to directly handle java.time types. Indeed, JDBC 4.2 compliant drivers may work if you call getObject and setObject on your ResultSet and PreparedStatement respectively. But if not, fallback to using the java.sql types. Notice the new methods added to these old classes including java.sql.Timestamp. The from method takes an Instant which we can extract from our ZonedDateTime objects.
java.sql.Timestamp tsStart = java.sql.Timestamp.from( zdtStart.toInstant() );
java.sql.Timestamp tsStop = java.sql.Timestamp.from( zdtTomorrowStart.toInstant() );
Now set these two variables are arguments on your PreparedStatement. Notice the comparison operators, testing for possible values that start on first moment of the day (>=) and running up to but not including the first moment of the next day (<).
String sql =
"SELECT * FROM event_" +
"WHERE when_ >= ? " +
"AND when_ < ? " +
";" ;
…
pstmt.setTimestamp( 1 , tsStart );
pstmt.setTimestamp( 2 , tsStop );
If you do indeed store integers instead of using date-time types, and you are storing milliseconds as a count from the epoch reference date-time of first moment of 1970 in UTC, then you can extract a number from each Instant. Remember that the java.time classes use a finer resolution of nanoseconds as do some databases such as H2 Database, and some databases such as Postgres capture date-time with a resolution of microseconds. So truncating to milliseconds may mean a loss of data.
long millisStart = tsStart.toInstant().toEpochMilli();
long millisStop = tsStop.toInstant().toEpochMilli();
Call setLong on your PreparedStatement.
pstmt.setLong( 1 , millisStart );
pstmt.setLong( 2 , millisStop );
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.
Related
This question already has answers here:
Android parsing String to Date time with SimpleDateFormat
(3 answers)
ParseException; must be caught (Try/Catch) (Java) [duplicate]
(1 answer)
Closed 2 years ago.
I have some dates in firebase and i need to retrieve as Miliseconds and do some operations with it.
the Date are like String in format "dd/MM/yyyy"
I tryed with a code like this, :
String myDate = "2014/10/29 18:10:45";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = sdf.parse(myDate);
long millis = date.getTime();
My code, basically i tryed to get the storeged String from firebase and convert to a Date for compare with the current day and show the diference of days. the error that I have, is only in the word "parse" of my code
refresh.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String mydate = model.getParto();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = sdf.parse(mydate);
}
});
but parse set an error
image of code and the string date in firebase
hope, someone can help
tl;dr
LocalDateTime
.parse(
"2014/10/29 18:10:45".replace( " " , "T" )
)
.atOffset( ZoneOffset.UTC )
.toInstant()
.toEpochMilli()
Need epoch reference
Representing a moment as a count of milliseconds requires a point in time as an epoch reference. You need to state the reference needed in your situation. I will assume the commonly used point of first moment of 1970 in UTC. But there are a couple dozen other points used by various systems. So you need to find out the meaning of your own data.
Need time zone or offset
Determining a moment requires more than a date and a time-of-day. You also need the context of a time zone or offset-from-UTC. Again, you need to specify this but did not. Is your example of ten minutes past six in the evening in Tokyo Japan, Toulouse France, or Toledo Ohio US? I will assume you mean an offset of zero hours-minutes-seconds. But again, you need to find out the meaning of your own data.
Avoid legacy date-time classes
Never use SimpleDateFormat, Date, or the other terrible date-time classes that were supplanted years ago by the modern java.time classes defined in JSR 310.
Date versus moment
Your Question in confused, referring to a date-only value as well as a date with time-of-day represented as milliseconds. These are two different kinds of data.
If representing a date-only, use LocalDate in Java and a type in your database akin to the SQL-standard DATE. I will ignore this date-only, and focus on tracking a moment.
Example code
Parse your input as LocalDateTime, after complying with standard ISO 8601 format by replacing SPACE in middle with a T.
A LocalDateTime does not represent a moment, is not a point on the timeline. You need to discover the zone/offset intended for you input, and apply. Apply the time zone intended for your input, to produce a ZonedDateTime. Or, if UTC (an offset of zero) was intended, apply a ZoneOffset to get an OffsetDateTime object. At this point we have determined a moment.
Extract a Instant object from the OffsetDateTime. Interrogate for a count of milliseconds since the epoch reference of 1970-01-01T00:00Z.
String myDate = "2014/10/29 18:10:45".replace( " " , "T" ) ; // Comply with ISO 8601 standard formatting.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ; // Assuming your data was intended to represent a moment as seen in UTC, with an offset of zero hours-minutes-seconds.
Instant instant = odt.toInstant() ; // Basic building-block class in java.time, representing a moment as seen in UTC.
long millisecondsSinceEpoch1970 = instant.toEpochMilli() ;
Your title mentions Firebase, but that seems irrelevant to your Question. so I will ignore that topic.
All the content in this Answer has been covered many times already on Stack Overflow. Search to learn more.
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 brought 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 (26+) bundle implementations of the java.time classes.
For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
just a question what i am doing wrong. I have this code:
public static int berechneSekundenwert(String datum, String zeit) throws ParseException {
Date dt = new Date();
SimpleDateFormat df = new SimpleDateFormat( "dd.MM.yyyy HH:mm:ss" );
dt = df.parse( datum+" "+ zeit);
int gesamtzeit = (int)dt.getTime();
return gesamtzeit;
}
Now my import format is:
09.11.2019 01:30:17
What i want to do is calculate the time passed for these dates, so i
can later sort them by time. But i get negative values?!
Example output (passed time, date, daytime):
-2120215336 30.09.2019 12:03:35
1757321960 25.09.2019 16:06:25
-2111322336 30.09.2019 14:31:48
-1281127040 21.08.2019 12:05:36
-1280681040 21.08.2019 12:13:02
377782960 09.09.2019 16:54:06
1301386664 09.11.2019 01:30:17
710621960 13.09.2019 13:21:25
712564960 13.09.2019 13:53:48
Shouldn't they all be positive, since java states, that the getTime function measures the time since 01.01.1970
Anyone knows what i did wrong?
Computers use something called a timestamp to represent dates. In Java, Date::getTime() returns the milliseconds passed since 1970-01-01T00:00:00.000Z up to the date in question as long (64-bit integer).
In the code presented, this value is narrowed down to an int (32-bit integer). By narrowing the long to an int, the highest 32 bits get cut of. The largest value representable by an int is 2^31 - 1. A quick calculation shows that:
(2^31 - 1) (milliseconds)
/ 1000 (milliseconds per second)
/ 60 (seconds per minute)#
/ 60 (minutes per hour)
/ 24 (hours per day)
= 24.8551348032 (days)
This means that after roughly 25 days, the int will overflow (as it is defined in the Two's compliment). Not to mention that a later point in time could have a lower value than an earlier point in time, thus the negative values.
To fix this issue1, I would suggest to define gesamtzeit as long.
Two remarks on your code:
java.util.Date is regarded as outdated. I would suggest to use java.time.Instant instead.
I would suggest to use English in the source code, only exception being you use domain-specific words that cannot (well) be translated to English.
1 This is only a temporary fix. All representation with a fixed number of bits will eventually overflow. In fact, all representation with any memory constraint at all will overflow eventually. I leave it up to the reader to find out when a 64-bit integer will overflow
tl;dr
See correct Answer by Turing85 about 32-bit versus 64-bit integers.
Use only modern java.time classes, never Date/SimpleDateFormat.
Consider the crucial issue of time zone or offset-from-UTC.
Educate the publisher of your data about the importance of (a) including zone/offset info, and (b) using ISO 8601 standard formats.
Code:
LocalDateTime.parse(
"09.11.2019 01:30:17" ,
DateTimeFormatter.ofPattern( "dd.MM.uuuu HH:mm:ss" )
)
.atOffset(
ZoneOffset.UTC
)
.toInstant()
.toEpochMilli()
See this code run live at IdeOne.com.
1573263017000
Details
The correct Answer by Turing85 addresses your specific question as to why the invalid negative numbers. But you have other problems.
ISO 8601
Now my import format is: 09.11.2019 01:30:17
I suggest you educate the publisher of this data about the ISO 8601 standard defining formats to use when communicating date-time values as text.
Legacy date-time classes
You are use terrible date-time classes that were supplanted years ago by the modern java.time classes defined in JSR 310. Never use Date or SimpleDateFormat.
Moment
Apparently you want to get a count of milliseconds since the epoch reference of first moment of 1970 in UTC. But doing that requires a moment, a specific point on the timeline.
Your input does not meet this requirement. Your input is a date and a time-of-day but lacks the context of an offset-from-UTC or a time zone.
So, take your example of 09.11.2019 01:30:17. We cannot know if this is 1:30 in the afternoon of Tokyo Japan, or 1:30 PM in Paris France, or 1:30 in Toledo Ohio US — which are all very different moments, several hours apart on the timeline.
So we must first parse your input as a LocalDateTime. This class represent a date and time without any concept of offset or zone.
String input = "09.11.2019 01:30:17" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd.MM.uuuu HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
Perhaps you know for certain the offset or zone intended by the publisher of this data. If so:
Suggest to the publisher of this data that they include the zone/offset info within their data.
Apply a ZoneOffset to get an OffsetDateTime, or a ZoneId to get a ZonedDateTime.
Perhaps you know for certain this input was intended for UTC, that is, an offset of zero hours-minutes-seconds.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
To get a count of milliseconds since 1970-01-01T00:00Z convert to the basic building-block class Instant.
Instant instant = odt.toInstant() ;
Interrogate for a count of milliseconds since epoch.
long millisSinceEpoch = instant.toEpochMilli() ;
Understand that your original code ignored the crucial issue of time zone & offset-from-UTC. So your code implicitly applies the JVM's current default time zone. This means your results will vary at runtime, and means you likely have incorrect results too.
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.
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.
why you downcast the return value ofgetTime()?
just make you method return long instead of int
and replace this line
int gesamtzeit = (int)dt.getTime();
with
long gesamtzeit = dt.getTime();
I have the following timestamp stored in a long variable: 1471906800000 this stores the date 18/01/2017 00:00:00
I'm trying to create another timestamp that will contain the same date as stored in the first timestamp, but with the time being 23:59:59 -
I don't even know where to start
How could I achieve this in the most simple way possible in Java?
Thanks.
Using Calendar will help you:
long l = 1471906800000l;
Date date = new Date(l);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
l = calendar.calendar.getTimeInMillis();
Both of the other Answers use outmoded classes, now supplanted by the java.time classes.
Perhaps your input number is a count of milliseconds from the epoch of first moment of 1970 in UTC (1970-01-01T00:00:00Z). But I do not get the result you stated in the question.
long input = 1_471_906_800_000L ;
Instant instant = Instant.ofEpochMilli( input );
input: 1471906800000
instant: 2016-08-22T23:00:00Z
But you expected the value of 18/01/2017 00:00:00, off by a few months. If your input is not a count of milliseconds from 1970-01-01T00:00:00Z, you need to edit your Question to specify.
If you made a mistake in your expected output, then let's proceed to set the time-of-day.
If you wanted the second before the end of the day, I suggest subtracting a second from the start of the following day rather than hard-coding the time of 23:59:59. That time-of-day may be invalid because of anomalies such as Daylight Saving Time (DST). Also, unless you meant intend to work in UTC, you need to move into the desired/expected time zone.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Extract a LocalDate, for a date-only value without time-of-day and without time zone.
LocalDate ld = zdt.toLocalDate();
Move to next day.
LocalDate ldNextDay = ld.plusDays( 1 );
Ask for first moment.
ZonedDateTime zdtNextDay = ldNextDay.atStartOfDay( z );
Subtract a second to move back into previous day.
ZonedDateTime zdtPreviousDay = zdtNextDay.minusSeconds( 1L );
However, I suspect you are taking the wrong approach to handling date-time values. Rather than trying to determine the end of a day, I strongly suggest you follow the common practice of using the Half-Open approach to spans of time. In Half-Open, the beginning is inclusive while the ending is exclusive.
So a full day starts with the first moment of one day and runs up to, but not including, the first moment of the next day. This way you avoid the problem of the last second or trying to get the infinitely divisible fraction of a second.
ZonedDateTime zdtDayStart = LocalDate.of( 2017 , Month.JANUARY , 18 ).atStartOfDay( 1 );
ZonedDateTime zdtDayStop = zdtDayStart.plusDays( 1 );
You may find the Interval class in the ThreeTen-Extra project helpful.
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.
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 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.
I'm assuming that you don't specifically want the time at 23:59:59, but rather a time 1 minute before the start of the next day.
You should use a date/time library. I know jodatime better, so this example is written using that, but you may be able to use the Java 8 time API instead.
DateTime today = new DateTime(1471906800000L, TIME_ZONE);
// You may want to check that today is actually at the start of the day.
// e.g. today.equals(today.withTimeAtStartOfDay());
DateTime lastMinuteOfToday =
today.toLocalDate()
.plusDays(1)
.toDateTimeAtStartOfDay(TIME_ZONE)
.minusMinutes(1);
long lastMinuteOfTodayMillis = lastMinuteOfToday.getMillis();
Knowing the timezone is important to do this correctly.
I try to format a time interval using SimpleDateFormat.
import java.text.*;
import java.util.*;
public class DateFormatTest {
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
long interval = 1000;
System.out.println("Interval in millis: " + interval);
System.out.println("Expected result: 00:00:01");
System.out.println("Result using Date and SimpleDateFormat: " +
sdf.format(new Date(interval)));
}
}
I get the following result:
Interval in millis: 1000
Expected result: 00:00:01
Result using Date and SimpleDateFormat: 01:00:01
I am in GMT+1 time zone. But it should not be reflected in the result.
Of course it can be solved with System.out.printf, but what I am searching is the reason.
I am in GMT+1 time zone. But should not be reflected in the result.
What makes you think so? new Date(0) is at 00:00AM GMT on Jan 1st 1970. So it is at 01:00AM if your default timezone is GMT + 1.
I am in GMT+1 time zone. But it should not be reflected in the result.
Then you should set the time zone in the SimpleDateFormat. SimpleDateFormat is doing exactly the right thing - it's formatting the instant in time (just after midnight UTC 1970) in the time zone it's working in.
To change the time zone, just use:
sdf.setTimeZone(TimeZone.getTimeZone("etc/UTC"));
It's not clear whether you should really be using SimpleDateFormat at all, though. You're not trying to format a date/time - you're trying to format an interval, given your variable name.
I suggest you use Joda Time which has a much richer type system, and will allow you to express what you really want.
Also, if you really want to use SimpleDateFormat, you probably want to use HH instead of hh in your format string. (hh is a 12-hour value, 1-12. You want 00:00:01, not 12:00:01.) hh is rarely appropriate when you don't also have an am/pm designator in your pattern.
Wrong data type
You are using the wrong class. You are trying to represent a duration of milliseconds and a time-of-day. Neither fits the Date class. That class represents a moment (a date, with time-of-day, in context of UTC).
Also, java.util.Date is a terrible class, designed by people who did not understand date-time handling. Now obsolete.
java.time
The modern solution uses java.time classes.
LocalTime
Specifically, LocalTime for a time-of-day using a generic 24-hour day, without a date, and without the context of a time zone or offset-from-UTC.
The start of a day for generic days is 00:00:00. We have a constant for that: LocalTime.MIN. But know that in various time zones, on various dates, the day may start at another time such as 01:00:00.
LocalTime lt = LocalTime.of( 15 , 30 ) ; // 3:30 PM.
Duration
To represent a span-of-time unattached to the timeline, on a scale of hours-minutes-seconds, use Duration class.
Duration d = Duration.ofMilliseconds( 1_000 ) ;
We can do math with date-time objects.
LocalTime lt = LocalTime.MIN.plus( d ) ;
You should know that java.time classes use a resolution of nanoseconds, much finer than the milliseconds used by the legacy date-time classes.
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.
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.
I got the following date format that I get from an API (Yes I tried to get them to change the API... dailywtf story):
\/Date(1310481956000+0200)\/
How can I convert this into a Java Date? (java.util.Date)
This comes from a .NET JSON web service.
Without knowing what the date/time string stands for, let me make a guess.
The 1310481956000 looks to be milliseconds after epoch, and the +0200 an offset relative to GMT.
The following code seem to indicate it as well:
final TimeZone tz = TimeZone.getTimeZone("GMT+0200");
final Calendar cal = Calendar.getInstance(tz);
cal.setTimeInMillis(1310481956000L);
final SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
f.setTimeZone(tz);
System.out.println(f.format(cal.getTime()));
Prints 2011-07-12 16:45:56 GMT+02:00
How can I convert this into a Java Date? (java.util.Date)
First, get "them" to clearly and precisely tell you exactly what that date format means. (If they won't or can't you could guess; see below.)
Next write a custom parser to parse the String and extract the information content.
Finally, convert the information content into a form that matches one of the Date constructors and create an instance.
My guess is that the 1310481956000 part is the number of milliseconds since the UNIX epoch (1970/01/01T00:00) and that the 0200 represents a timezone offset of 2 hours (MET?). However, you shouldn't rely on a guess. Get "them" to give you the specification, or at least a number of examples and the actual times/timezones that they correspond to.
You'll have to get the format from the API provider but it seems like a epoch + an offset for time zones. To convert it you could try.
final String fromAPI = "1310481956000+0200"
final String epochTime = fromAPI.substring(0, fromAPI.indexOf("+"));
final String timeZoneOffSet = fromAPI.substring(fromAPI.indexOf("+"), fromAPI.size());
Date date = new Date(Long.parseLong(epochTime));
Notice i'm not doing anything with the time zone (if that's what it is). You'll have to deal with that but this should get you on the right path.
tl;dr
Instant.ofEpochMilli(
java.lang.Long.parseLong( "1310481956000" )
).atOffset( ZoneOffset.of( "+0200" ) )
Using java.time
The accepted Answer is correct but outdated. The modern way to handle this is through the java.time classes.
The input is ambiguous. Is it a count from the Unix epoch reference date-time of first moment of 1970 in UTC 1970-01-01T00:00:00:Z and then adjusted by two hours ahead of UTC? If so, this example code seen here works.
First parse that input number as a 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).
Extract the first portion of your string and parse as a long.
long millisSinceEpoch = java.lang.Long.parseLong( "1310481956000" );
Instant instant = Instant.ofEpochMilli( millisSinceEpoch );
instant.toString(): 2011-07-12T14:45:56Z
Extract the last portion of your string and parse as a ZoneOffset.
ZoneOffset offset = ZoneOffset.of( "+0200" );
Apply the offset to the Instant to get an OffsetDateTime.
OffsetDateTime odt = instant.atOffset( offset );
odt.toString(): 2011-07-12T16:45:56+02:00
Note that an offset-from-UTC is not a time zone. A zone is an offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST).
Avoid java.util.Date whenever possible. But if you must use one, you can convert to/from java.time. Look to new conversion methods added to the old classes.
java.util.Date d = java.util.Date.from( odt.toInstant() );
d.toString(): Tue Jul 12 14:45:56 GMT 2011
See live code at IdeOne.com covering this entire example.
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.
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 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.