我有一个字符串“ Mon Jan 01 00:00:00 AEDT 1990”,我需要将其转换为“ yyyyMMdd”格式,因此在这种情况下应为“ 19900101”。
我认为可以使用正则表达式来做到这一点,这样我就可以从字符串中提取年份,月份(但需要将Jan转换为01等)和日期,但是我并不精通正则表达式。有人有什么想法吗?
答案 0 :(得分:6)
Regex太过分了。
这里是使用Java中内置的 java.time 类的单线解决方案。
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 类。
指定自定义格式设置模式以适合您的输入。
指定语言环境以方便翻译星期几的名称和月份的名称。
ZonedDateTime
解析为ZonedDateTime
,即特定区域(时区)的人们使用的挂钟时间所看到的时刻。
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 [澳大利亚/悉尼]
顺便说一句,您输入的字符串格式为可怕的。它使用2-4个字符的伪时区,它们不是实际的时区,不是标准化的,也不是唯一的!另一个问题取决于英语。而且很难解析。教育人们发布有关ISO 8601标准之美的数据,该标准是为交换日期时间值作为文本而创建的。
LocalDate
您只想要日期。因此,提取一个LocalDate
。
LocalDate ld = zdt.toLocalDate() ; // Extract only the date, leaving behind the time-of-day and the time zone.
您所需的输出格式已在DateTimeFormatter
类中定义。日期的标准ISO 8601格式为YYYY-MM-DD。的一种变体称为“基本”,表示它最大程度地减少了分隔符YYYYMMDD的使用。
String output = ld.format( DateTimeFormatter.BASIC_ISO_DATE ) ;
19900101
答案 1 :(得分:2)
检查这样是否有帮助
//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));
答案 2 :(得分:1)
现在假设每个传递的字符串中的每个月和日名称与枚举name
值之一匹配(即“ Mar” 与{中的字段name
匹配) {1}},而“ Marc” 或“ March” 则不同),并且您提供给我们的示例字符串的格式是真正一致的,因为它不是主题要在运行时进行更改,并且将始终保持Month.MARCH
,其中year始终是4位数字,以下代码应给出确切的答案:
主班
<day-name> <month> <day> <time> <zone> <year>
CustomDateFormat类
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);
}
输出
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);
}
}
让我知道这是否满足您的要求,是否需要满足任何其他条件,或者是否考虑了特殊情况。这是一个非常简单的实现,因此无需花费任何时间即可将其调整为更具体的需求。
编辑:修正一些实现错误,将示例字符串更改为自定义字符串,并删除多余的输出行。