4

How can I convert time from unix timestamp to week day? For example, I want to convert 1493193408 to Wednesday.

I tryed code above, but It always shows Sunday..

SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
Date dateFormat = new java.util.Date(1493193408);
String weekday = sdf.format(dateFormat );
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
MrStuff88
  • 327
  • 3
  • 11
  • @RobinTopper edited – MrStuff88 Apr 28 '17 at 09:07
  • 1
    (1) Be aware that the week day depends on time zone. At the Unix time given, in time zone `America/Anchorage` it is still Tuesday. (2) Even on Android you may discard the now very old classes `SimpleDateFormat` and `Date` and use the newer classes in `java.time`. These are generally much more programmer-friendly. See [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP). – Ole V.V. Apr 28 '17 at 09:29
  • 1
    FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html), and `java.text.SimpleTextFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Apr 28 '17 at 21:32

8 Answers8

4

Using java.time

The other Answers use the troublesome old date-time classes, now legacy, supplanted by the java.time classes.

Time zone is crucial in determining a date, and therefore getting a day-of-week.

Get an Instant from your count of while seconds since the epoch of 1970 in UTC. Apply a time zone to get a ZonedDateTime. From there extract a DayOfWeek enumerate object. Ask that object to automatically localize to generate a string of its name.

Instant.ofEpochSecond( 1_493_193_408L )
        .atZone( ZoneId.of( "America/Montreal" ))
        .getDayOfWeek()
        .getDisplayName( TextStyle.FULL , Locale.US )

For Android, see the ThreeTenABP project for a back-port of most of the java.time functionality.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • You should either use `Instant.ofEpochSecond()` as in [Pallavi Sonal’s answer](http://stackoverflow.com/a/43676892/5772882) or multiply by 1000. As the code stands, the result is `Sunday`. – Ole V.V. Apr 28 '17 at 11:35
  • 1
    Had never seen a number defined like `1_493_193_408` but that is quite handy: http://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html – greenapps Apr 28 '17 at 12:18
  • @OleV.V. Thanks, fixed. – Basil Bourque Apr 28 '17 at 19:35
  • @greenapps Don't forget the `L` on the end of `1_493_193_408` to make it a numeric literal of type `long` rather than default of `int`. – Basil Bourque Apr 29 '17 at 21:58
3

You need to multiply it by 1000 since Java and Unix time are not the same.

 SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
Date dateFormat = new java.util.Date(1493193408L * 1000);
String weekday = sdf.format(dateFormat );
Alex
  • 3,382
  • 2
  • 32
  • 41
  • 1
    If you want to use the outdated `Date` class you indeed need to multiply by 1000. You also need to take `int` overflow into account. Your code incorrectly yields Monday. – Ole V.V. Apr 28 '17 at 11:29
  • fixed. The Calendar also requires millis or a Date object to set a time. So either way he needs to convert the unix epoch time to java time. – Alex Apr 28 '17 at 11:36
2

You can use a calendar instance because it provides you methods for getting that information:

Date date = new Date(1493193408000L);
Calendar c = Calendar.getInstance();
c.setTime(date);

System.out.println(c.get(Calendar.DAY_OF_WEEK));
System.out.println(c.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.US));
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
2

The Date constructor has the following description:

Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.

Your timestamp is in seconds, if you multiply by 1000 (to get milliseconds) you get the expected answer:

 SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
 Date dateFormat = new java.util.Date(1493193408000L);
 System.out.println(dateFormat);
 String weekday = sdf.format(dateFormat);
 System.out.println(weekday);

Which prints

Wed Apr 26 09:56:48 CEST 2017
Wednesday
Robin Topper
  • 2,295
  • 1
  • 17
  • 25
1

dateFormatStart != dateFormat

You could also check using:

SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
Date dateFormat = new Date(System.currentTimeMillis());
String weekday = sdf.format(dateFormat);
iGio90
  • 290
  • 1
  • 4
  • 15
1

Here is right code for you:

SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
Date dateFormat = new java.util.Date(1493193408 * 1000);
String weekday = sdf.format(dateFormat );

There is documentation for Java date

kutsyk
  • 185
  • 1
  • 13
  • This is not the exactly right code. The result on my computer (Danish locale) is `mandag`, which is Danish for Monday. The desired result was Wednesday. Your problem is `int` overflow: the result of your multiplication is `-1455211008`. – Ole V.V. Apr 28 '17 at 11:24
1

You can do the same with the new JDK 8 date time classes. Local date and time is calculated using the seconds from Unix Epoch and then it can be formatted with a specific pattern. The conversion to date time takes into account the Zone as well, I have used the default Zone, but it can be modified to use a specific zone.

ZonedDateTime ldt = ZonedDateTime.ofInstant(Instant.ofEpochSecond(1493193408), ZoneId.systemDefault());
System.out.println(ldt.format(DateTimeFormatter.ofPattern("EEEE")));
Pallavi Sonal
  • 3,661
  • 1
  • 15
  • 19
  • LocalDateTime is the wrong class here as it lacks any concept of time zone or offset-from-UTC. So you may not get the correct day-of-week as expected by the user. ZonedDateTime is the correct way to go. – Basil Bourque Apr 28 '17 at 09:47
  • 1
    Thanks @BasilBourque for pointing that out. Updated the code. – Pallavi Sonal Apr 28 '17 at 09:52
  • Ah, `ofEpochSecond()`. I was about to forget about that one. Obviously the right method to use here. – Ole V.V. Apr 28 '17 at 11:16
0

It’s been said already: your problem is your are feeding number seconds since the Unix epoch into a Date when it expects the number of milliseconds (then one would have expected multiplying by 1000 to be simple, but a couple of the other answers got that part wrong).

If you are going to work with dates, times or weekdays in your app, I agree with the answers that recommend that you consider the newer classes in java.time. They are much nicer to work with. Your code will more directly express your intent.

But if you only need the weekday, a dependency on a third party library may be overkill. I still recommend keeping a distance to the oldfashioned classes SimpleDateFormat, Date and Calendar, though. Is there a third option? There certainly is! A simple oneliner, even:

    String weekday = String.format(Locale.ENGLISH, "%tA", 1493193408 * 1000L);

This yields Wednesday as desired. You must still be aware that the result depends on your computer’s time zone setting, though.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161