Reputation: 808
EDIT: Removed the '*1000' and still getting incorrect date but updated the log below to show what I am now getting.
Below is my code snippet and my log and I thought I implemented it correctly so I don't know why it isn't giving me the correct conversion:
NewFoodItem foodItem = data.get(position);
String date = new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new java.util.Date (foodItem.date));
String a = Integer.toString(foodItem.date);
Log.d("returnedDate:", a);
Log.d("formattedDate:", date);
It won't let me post an image but the log looks like this:
D/returnedDate: 1409012824
D/formattedDate: 01/17/1970 02:23:32
D/returnedDate: 1409013004
D/formattedDate: 01/17/1970 02:23:33
Upvotes: 1
Views: 2136
Reputation: 339561
The Answer by Andrew T. is correct: integer overflow. But the example code is now outmoded.
The modern approach uses the java.time classes.
The Instant
class represents a moment. Like java.util.Date
, Instant
counts from the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00Z. But Instant
uses a finer resolution of nanoseconds rather than milliseconds.
Append an L
to the end of your numeric literal to indicate long
type. Use underscores wherever you like to group your digits, with no meaning added (ignored by compiler).
long input = 1_409_012_824L ;
Instant instant = Instant.ofEpochSecond( input ) ;
Generate a textual representation of the value in standard ISO 8601 format.
String output = instant.toString() ;
2014-08-26T00:27:04Z
For more flexibility in generating text, convert to a OffsetDateTime
.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Automatically localize the output using a DateTimeFormatter
.
Locale locale = Locale.US ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( locale ) ;
String output2 = odt.format( f ) ;
Aug 26, 2014, 12:27:04 AM
See this code run live at IdeOne.com.
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?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
Upvotes: 3
Reputation: 4707
I just tested with some assumption, and it seems that the problem is related to integer overflow.
I assume you defined NewFoodItem.date
as int
, instead of long
. Hence, when you multiply the date * 1000
(both are int
), it returns int
.
int d = 1409012824; // foodItem.date
int d1000 = d * 1000; // returns 263550912 because of overflow, instead of 1409012824000
String date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
.format(new Date(d1000)); // returns 01/04/1970 08:42:30
When I try changing one of them to long
, it behaves as expected
// case 1
long d = 1409012824;
long d1000 = d * 1000; // now returns 1409012824000 correctly
String date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
.format(new Date(d1000)); // returns 08/26/2014 08:27:04
// case 2
int d = 1409012824;
long d1000 = d * 1000L; // note the "L" suffix to indicate the number as long
long d1000f = d * 1000; // FAIL, still returns 263550912 because of integer overflow
String date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
.format(new Date(d1000)); // returns 08/26/2014 08:27:04
String date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
.format(new Date(d1000f)); // returns 01/04/1970 08:42:30
Generally when working with Date
in Java, we define them as long
since normally they are in millisecond. For easier maintenance, changing the type of NewFoodItem.date
as long
is the preferred one; much better if it's in millisecond also.
Upvotes: 2