How to convert this string “Mon Jan 01 00:00:00 AE

2019-08-23 03:09发布

This question already has an answer here:

I have a string "Mon Jan 01 00:00:00 AEDT 1990" and I need to convert it into the format "yyyyMMdd" so in this case it would be "19900101".

I think it's possible to do this with Regular Expressions so that I could pull out the year, month(but would need to convert Jan to 01 and etc) and day from the string but I am not well versed in Regular Expressions. Anyone have any ideas?

3条回答
狗以群分
2楼-- · 2019-08-23 03:20

Check if something like this helps

//date string
String soTime = "Mon Jan 04 12:30:23 AEDT 1990";

//Format
SimpleDateFormat so = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");

SimpleDateFormat desiredFormat = new SimpleDateFormat("yyyyMMdd");
desiredFormat.setTimeZone(TimeZone.getTimeZone("Australia/Sydney"));

Date sodate = so.parse(soTime);
System.out.println("DAY : " + desiredFormat.format(sodate));

Parse date with AEDT and AEST time zone in java

查看更多
够拽才男人
3楼-- · 2019-08-23 03:24

tl;dr

Regex is overkill.

Here is a one-liner solution using java.time classes built into Java.

ZonedDateTime                            // Represent a moment as seen through the wall-clock time used by the people of a certain region (a time zone).
.parse(                                  // Parse the input text.
    "Mon Jan 01 00:00:00 AEDT 1990" ,     
    DateTimeFormatter.ofPattern( 
        "EEE MMM dd HH:mm:ss z uuuu" ,   // Specify a custom formatting pattern to match our input.
        Locale.US                        // Specify a `Locale` for the human language to use in translating the name of month& day-of-week.
    )                                    // Returns a `DateTimeFormatter` object.
)                                        // Returns a `ZonedDateTime` object.
.toLocalDate()                           // Extract the date, without time-of-day and without time zone. 
.format(                                 // Generate text to represent the value of our `LocalDate` object.
    DateTimeFormatter.BASIC_ISO_DATE     // Use the predefined formatting pattern YYYYMMDD.
)                                        // Returns a String.

19900101

java.time

Regex is overkill for this.

The modern approach uses java.time classes.

Specify a custom formatting pattern to fit your input.

Specify a locale to facilitate translating the name of day-of-week and name of month.

ZonedDateTime

Parse as a ZonedDateTime, a moment as seen through the wall-clock time used by the people of a specific region (a time zone).

String input = "Mon Jan 01 00:00:00 AEDT 1990";
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM dd HH:mm:ss z uuuu" , locale );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );

System.out.println( "zdt: " + zdt );

zdt: 1990-01-01T00:00+11:00[Australia/Sydney]

By the way, your input string is in a terrible format. It uses the 2-4 character pseudo-zones that are not actual time zones, not standardized, and are not unique! Another problem is depending on English. And it is difficult to parse. Educate the people publishing your data about the beauty of the ISO 8601 standard, created for exchanging date-time values as text.

LocalDate

You want only the date. So extract a LocalDate.

LocalDate ld = zdt.toLocalDate() ;  // Extract only the date, leaving behind the time-of-day and the time zone.

Your desired output format has already been defined in the DateTimeFormatter class. The standard ISO 8601 format for a date is YYYY-MM-DD. A variation of that is known as "Basic" meaning it minimizes the use of delimiters: YYYYMMDD.

String output = ld.format( DateTimeFormatter.BASIC_ISO_DATE ) ;

19900101

查看更多
放荡不羁爱自由
4楼-- · 2019-08-23 03:40

Now assuming that each month and day names inside each passed string is matching one of enum name values (i.e "Mar" matches the value of field name in Month.MARCH, while "Marc" or "March" do not) and the format of the sample string you gave us is truly consistent, as in it is no subject to change during runtime and will always remain <day-name> <month> <day> <time> <zone> <year> where year is always a 4 digit number, the following code should answer give you exactly what you want:

Main Class

public static void main(String[] args) {

    String time = "Mon Jul 05 00:00:00 AEDT 1990";
    int result = CustomDateFormat.parseToInt(time);
    System.out.println("Parsed in format [yyyyMMdd]: " + result);
}

CustomDateFormat Class

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CustomDateFormat {

    private static final Pattern STANDARD_PATTERN =
    Pattern.compile("^(?:[a-zA-Z]{3})\\s([a-zA-Z]{3})\\s([0-9]{2}).*([0-9]{4})");

    /*
     * This is just in case you want
     * the name of the day as well
     */
    public enum Day {

        MONDAY("Mon", "Monday"),
        TUESDAY("Tue", "Tuesday"),
        WEDNESDAY("Wed", "Wednesday"),
        THURSDAY("Thu", "Thursday"),
        FRIDAY("Fri", "Friday"),
        SATURDAY("Sat", "Saturday"),
        SUNDAY("Sun", "Sunday");

        final String shortName;
        final String fullName;

        Day(String name1, String name2) {
            this.shortName = name1;
            this.fullName = name2;
        }

        public static String getFullName(String alias) {
            for (Day d : Day.values()) {
                if (d.shortName.equals(alias))
                    return d.fullName;
            }
            return "";
        }
    }

    public enum Month {

        JANUARY("Jan", 1), FEBRUARY("Feb", 2),
        MARCH("Mar", 3), APRIL("Apr", 4),
        MAY("May", 5), JUNE("Jun", 6),
        JULY("Jul", 7), AUGUST("Aug", 8),
        SEPTEMBER("Sep", 9), OCTOBER("Oct", 10),
        NOVEMBER("Nov", 11), DECEMBER("Dec", 12);

        final String name;
        final int value;

        Month(String name, int value) {
            this.name = name;
            this.value = value;
        }

        public static int getMonth(String month) {
            for (Month m : Month.values()) {
                if (m.name.equals(month))
                    return m.value;
            }
            return 0;
        }
    }

    public static int parseToInt(String date) {

        System.out.println("Parsing date: " + date);
        Matcher matcher = STANDARD_PATTERN.matcher(date);

        if (matcher.find() && matcher.groupCount() == 3)
        {
            int month = Month.getMonth(matcher.group(1));
            int day = Integer.valueOf(matcher.group(2));
            int year = Integer.valueOf(matcher.group(3));

            if (day == 0 || month == 0) {
                throw new IllegalStateException("Unable to parse day or month from date " + date);
            }
            else return Integer.valueOf(year + "0" + month + "0" + day);
        }
        else throw new IllegalStateException("Unable to parse date " + date);
    }
}

Output

Parsing date: Mon Jul 05 00:00:00 AEDT 1990
Parsed in format [yyyyMMdd]: 19900705

Let me know if this meets your requirements and if any other conditions need to be met or special case scenarios considered. It's a fairly simple implementation so it should take no time to adjust it to more specific needs.

EDIT: Fix some implementation mistakes, change sample string to a custom one and remove redundant output line.

查看更多
登录 后发表回答