Search code examples
javaandroiddate-formatepoch

Convert Epoch Date in Date time format 1980-01-01


This is my code

private Date getReferenceDate(int seg) {

    switch (seg) {
        case 1:
        case 2:
        case 3:
            return new Date(1980-01-01);
        case 31:
        case 32:
        case 33:
            return new Date(1970-01-01);
        default:
            return new Date(1980-01-01);
    }
}

 private Date getDateFormat(int time, int seg) {
    Date date = getBaseReferenceDate(seg);
    date.setSeconds(date.getSeconds() + time);
    date.setHours(date.getHours() - 5);
    date.setMinutes(date.getMinutes() - 30);
    date.setSeconds(date.getSeconds()-1);
    return date;
}

I have Date in 1185106460 format i want to convert it into 2017-07-21 12:14:20 this format I get Wrong output for 1980-01-01


Solution

  • I think the following is what you want.

    Even though you are on Android and thus don’t have the modern Java date and time API built-in, I am using it because it’s much more convenient, in particular for this kind of operation. You get it in ThreeTenABP, see How to use ThreeTenABP in Android Project.

    private static OffsetDateTime getReferenceDate(int seg) {
        int baseYear = 1970;
        if (seg >= 31 && seg <= 33) {
            baseYear = 1980; 
        }
        return OffsetDateTime.of(LocalDate.of(baseYear, Month.JANUARY, 1), 
                                 LocalTime.MIDNIGHT,
                                 ZoneOffset.UTC);
    }
    
    private static OffsetDateTime getDateFormat(int time, int seg) {
        return getReferenceDate(seg).plusSeconds(time);
    }
    

    See it work:

        System.out.println(getDateFormat(1185106460, 1));
    

    This prints:

    2007-07-22T12:14:20Z
    

    This is the date and time you asked for.

    If you want just the date in yyyy-mm-dd format:

        System.out.println(getDateFormat(1185106460, 1)
                .format(DateTimeFormatter.ISO_LOCAL_DATE));
    

    This prints

    2007-07-22
    

    If you need an outdated Date object, for example for some legacy API that you cannot change:

        System.out.println(DateTimeUtils.toDate(getDateFormat(1185106460, 1).toInstant()));
    

    On my computer this prints:

    Sun Jul 22 14:14:20 CEST 2007
    

    It’s the same point in time, only Date.toString() formats it into the JVM’s time zone setting. In Java 8 or later the conversion would be

        System.out.println(Date.from(getDateFormat(1185106460, 1).toInstant()));
    

    What were you doing wrong? First, you were using the deprecated methods in Date. These were deprecated for a reason, they are unreliable across time zones, so you don’t want to use them. You may also have intended to use one of the deprecated Date constructors, but you are using the non-deprecated one. 1980-01-01 is an arithmetic expression with two subtractions. 01 is an octal integer literal with the value 1, so the result of the expression is 1978. You pass the 1978 into the constructor Date(long date), where they are interpreted as milliseconds since the epoch, 1970-01-01T00:00:00Z.

    In the case where you intended the mentioned epoch as reference, you are getting close, just 1968 milliseconds off. I suspect that your subtraction of 1 second in the end is your attempt to compensate for this. In the case where you intended the 1980 reference, you are 10 years off, save 1978 milliseconds. Which lead to this question.

    In any case, Date is long outdated and not suited for what you are trying to do. I recommend ThreeTenABP as I said. If you really, really don’t want to rely on an external library (just until the modern API comes to Android), you may look into the Calendar and/or GregorianCalendar classes, but they are troublesome and errorprone, just be warned.