0

I can calculate the time in milliseconds with the following Ruby snippet:

$ irb
> require 'date'
 => true 
> Date.new(2014,9,5).to_time
 => 2014-09-05 00:00:00 +0200
> Date.new(2014,9,5).to_time.to_i * 1000
 => 1409868000000

1409868000000 is the desired result.
How can I get the same result with Java? I set the time zone to CEST since it seems to be what Ruby works with. So I tried this:

GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("CEST"));
calendar.set(2014, 9, 5);
System.out.println("" + calendar.getTimeInMillis());
// Returns: 1412498241422
JJD
  • 50,076
  • 60
  • 203
  • 339

4 Answers4

8

There are three problems with your current code:

  • "CEST" isn't a time zone Java recognized. Try Europe/Paris instead, as a European time zone
  • java.util.Calendar uses 0-based months (yes, it's awful)
  • You haven't cleared out the time part of the Calendar, so it'll give you the current time of day, on that date

This works:

import java.util.*;

public class Test {
    public static void main(String[] args) throws Exception {
        TimeZone zone = TimeZone.getTimeZone("Europe/Paris");
        Calendar calendar = new GregorianCalendar(zone);
        // Month 8 = September in 0-based month numbering
        calendar.set(2014, 8, 5, 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        System.out.println(calendar.getTimeInMillis());
    }
}

If you know the month in advance, you can use the constants instead:

calendar.set(2014, Calendar.SEPTEMBER, 5, 0, 0, 0);

If you can possibly move to using Joda Time or java.time from Java 8, however, those are much cleaner APIs.

For example, in Joda Time:

import org.joda.time.*;

class Test {
    public static void main(String[] args) {
        DateTimeZone zone = DateTimeZone.forID("Europe/Paris");
        // Look ma, a sensible month numbering system!
        LocalDate date = new LocalDate(2014, 9, 5);
        DateTime zoned = date.toDateTimeAtStartOfDay(zone);
        System.out.println(zoned.getMillis());
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*, released in March 2014.

Also, quoted below is a notice at the Home Page of Joda-Time:

Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

Solution using java.time, the modern Date-Time API:

import java.time.LocalDate;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {    

        long millis = LocalDate.of(2014, 9, 5)
                                .atStartOfDay(ZoneId.of("Europe/Paris"))
                                .toInstant()
                                .toEpochMilli();
        
        System.out.println(millis);
    }
}

Output:

1409868000000

ONLINE DEMO

Avoid using two/three/four letter abbreviation for timezone name. Use the convention Region/City e.g. Europe/Paris. You can get the list of timezone names using ZoneId.getAvailableZoneIds().

Learn more about the modern Date-Time API from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0

You can use System.currentTimeMillis() to get the time in milliseconds since start of epoch.

If you want to translate to the same baseline as Ruby is using, that will be as simple as adding some fixed offset (i.e., use System.currentTimeMillis() + DELTA). You should be able to calculate DELTA by trying it in Ruby and in Java on some fixed date to see what the difference is.

Are you sure that Ruby's calculation isn't locale-dependent, though? It would be odd (not to say barely plausible) if it routinely used CEST.

chiastic-security
  • 20,430
  • 4
  • 39
  • 67
0

try

calendar.set(2014, 8, 5, 0, 0, 0);
System.out.println("" + (calendar.getTimeInMillis() / 1000) * 1000);

see http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#set(int,%20int,%20int,%20int,%20int)

Scary Wombat
  • 44,617
  • 6
  • 35
  • 64