Convert date in string(Mon Jan 16:20:12 India Standard Time 2014) to java.util.date in JAVA

StackOverflow https://stackoverflow.com/questions/21089707

Вопрос

I want to convert this (Mon Jan 16:20:12 India Standard Time 2014) Date in string to java.util.Date in java how can I do it. I want the date in the following format.

SimpleDateFormat formatter = new SimpleDateFormat(
                "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);

Actually the Date (Mon Jan 16:20:12 India Standard Time 2014) is argument from MFC application which will be launching a executable jar file and the date in string will be its argument. MFC Code that will launch the executable jar. with argument.

CString csCurrentTime = CTime::GetCurrentTime().Format("%a %b %X %Z %Y");
    TRACE(csCurrentTime);
    if (CreateProcess(m_csJrePath, TEXT(" -jar DbxUpldDwnld.jar %s",csCurrentTime), NULL, NULL, false, CREATE_NO_WINDOW, NULL, NULL, (LPSTARTUPINFOA)&siStartupInfo, &piProcessInfo) == false) {
        AfxMessageBox(_T("Please install Java Runtime Environment(JRE) on your PC\n Or JRE not found on given path in INI File."), MB_ICONERROR);
        CloseHandle(piProcessInfo.hProcess);
        CloseHandle(piProcessInfo.hThread);
        return;
    }

Also will it be possible to get the date with spaces as single argument in java. Please Help me, am new to MFC.

Это было полезно?

Решение

You need to use another SimpleDateFormat that has the format of your time-string to do the parsing. For your example, this one should work:

String time = "Mon Jan 16:20:12 India Standard Time 2014";
SimpleDateFormat parser = new SimpleDateFormat("E MMM HH:mm:ss z yyyy", Locale.US);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
System.out.println(formatter.format(parser.parse(time)));

As @TimB points out, all the date and time patterns can be found in the JavaDoc for SimpleDateFormat.

Другие советы

java.time

Update:

Thanks to Ole V.V.

For a more general solution, replace .parseDefaulting(ChronoField.DAY_OF_MONTH, date.getDayOfMonth()) with .parseDefaulting(ChronoField.ALIGNED_WEEK_OF_MONTH, 1) which will also simplify the solution by removing the need to obtain the LocalDate first.

Demo:

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.util.Locale;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                .parseCaseInsensitive()                              
                                .appendPattern("E MMM H:m:s")
                                .appendLiteral(' ')
                                .appendZoneText(TextStyle.FULL)
                                .appendLiteral(' ')
                                .appendPattern("u")
                                .parseDefaulting(ChronoField.ALIGNED_WEEK_OF_MONTH, 1)                                
                                .toFormatter(Locale.ENGLISH);

        // Test
        Stream.of(
                    "Mon Jan 16:20:12 India Standard Time 2014",
                    "Mon Feb 16:20:12 India Standard Time 2014"
        ).forEach(s -> System.out.println(ZonedDateTime.parse(s, dtf)));
    }        
}

Output:

2014-01-06T16:20:12+05:30[Asia/Kolkata]
2014-02-03T16:20:12+05:30[Asia/Kolkata]

Original answer:

The legacy date-time API (java.util date-time types and their formatting API, SimpleDateFormat) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API*.

Solution using the modern API:

Your date-time string does not have day-of-month. It means that you need to provide a day-of-month to the DateTimeFormatter which you can do by using DateTimeFormatterBuilder#parseDefaulting. In order to obtain the first Monday of the month, the idiomatic way is to use TemporalAdjusters.firstInMonth.

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjusters;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "Mon Jan 16:20:12 India Standard Time 2014";

        LocalDate date = LocalDate.of(2014, Month.JANUARY, 1)
                                .with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));

        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                .parseCaseInsensitive()
                                .parseDefaulting(ChronoField.DAY_OF_MONTH, date.getDayOfMonth())
                                .appendPattern("E MMM H:m:s")
                                .appendLiteral(' ')
                                .appendZoneText(TextStyle.FULL)
                                .appendLiteral(' ')
                                .appendPattern("u")
                                .toFormatter(Locale.ENGLISH);

        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
        System.out.println(zdt);
    }
}

Output:

2014-01-06T16:20:12+05:30[Asia/Kolkata]

For any reason, if you need to convert this object of ZonedDateTime to an object of java.util.Date, you can do so as follows:

Date date = Date.from(zdt.toInstant());

Learn more about the 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top