Java数据处理格式不正确
首先,我是一名学习Java的C开发人员。作为练习,我正在转换一个用C编写的程序,在解析从html表单提交的日期时遇到问题。表单作为电子邮件发送,java程序读取电子邮件并解析正文。我有一个下拉日历供我的窥视者选择一个日期,但总有一些混蛋不得不输入它,把一切都搞砸了。目前,我正在我的代码中执行此操作:Java数据处理格式不正确,java,Java,首先,我是一名学习Java的C开发人员。作为练习,我正在转换一个用C编写的程序,在解析从html表单提交的日期时遇到问题。表单作为电子邮件发送,java程序读取电子邮件并解析正文。我有一个下拉日历供我的窥视者选择一个日期,但总有一些混蛋不得不输入它,把一切都搞砸了。目前,我正在我的代码中执行此操作: public void SetDatePlayed(String datePlayed) { this.datePlayed = LocalDate.parse(datePlayed); }
public void SetDatePlayed(String datePlayed)
{
this.datePlayed = LocalDate.parse(datePlayed);
}
传递的datePlayed是一个字符串,通常格式为yyyy-MM-dd,但当然有人输入了3/7,而不是使用表单上的日历下拉列表。this.datePlayed是本地日期。在C中,我将以一个假定为2020年的日期结束——没问题。LocalDate确实希望它采用yyyy-MM-dd格式,我不知道Java的最佳实践是什么。我整个上午都在谷歌上搜索,没有发现这是其他人的问题。我不在乎是否使用LocalDate,但我确实需要它是一个日期数据类型,以便我以后可以进行日期检查、排序、搜索等。我看到了对您的问题的两种可能的解释。我不确定是哪一个,所以我会两个都回答 如何将没有年份的格式(如M/D3/7)中的日期字符串解析为LocalDate 你没有。根据定义,LocalDate必须具有年、月和日。如果你只有一个月和一天,那就是一个月: 如果要将当前年份添加到其中,可以稍后执行:
LocalDate ld = md.atYear(Year.now(/*optionally insert time zone*/).getValue());
如何处理yyyy-MM-dd和M/d模式
这里有一种方法:创建一个可以识别这两种模式的DateTimeFormatter,将字符串解析为临时Accessor,检查临时Accessor是否支持年份字段:
TemporalAccessor ta = DateTimeFormatter.ofPattern("[M/d][yyyy-MM-dd]").parse("3/7");
if (ta.isSupported(ChronoField.YEAR_OF_ERA)) { // yyyy-MM-dd
LocalDate ld = LocalDate.from(ta);
} else if (ta.isSupported(ChronoField.MONTH_OF_YEAR)) { // M/d
MonthDay md = MonthDay.from(ta);
} else {
// user has entered an empty string, handle error...
}
我认为对你的问题有两种可能的解释。我不确定是哪一个,所以我会两个都回答 如何将没有年份的格式(如M/D3/7)中的日期字符串解析为LocalDate 你没有。根据定义,LocalDate必须具有年、月和日。如果你只有一个月和一天,那就是一个月: 如果要将当前年份添加到其中,可以稍后执行:
LocalDate ld = md.atYear(Year.now(/*optionally insert time zone*/).getValue());
如何处理yyyy-MM-dd和M/d模式
这里有一种方法:创建一个可以识别这两种模式的DateTimeFormatter,将字符串解析为临时Accessor,检查临时Accessor是否支持年份字段:
TemporalAccessor ta = DateTimeFormatter.ofPattern("[M/d][yyyy-MM-dd]").parse("3/7");
if (ta.isSupported(ChronoField.YEAR_OF_ERA)) { // yyyy-MM-dd
LocalDate ld = LocalDate.from(ta);
} else if (ta.isSupported(ChronoField.MONTH_OF_YEAR)) { // M/d
MonthDay md = MonthDay.from(ta);
} else {
// user has entered an empty string, handle error...
}
您可以使用和来提供该年的默认值
基于,可以这样做:
static LocalDate parseLoosely(String text) {
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("[uuuu-M-d][M/d/uuuu][M/d]")
.parseDefaulting(ChronoField.YEAR, Year.now().getValue())
.toFormatter();
return LocalDate.parse(text, fmt);
}
警告:不要将格式化程序缓存在静态字段中,因为如果程序可能在除夕期间运行(网络应用程序可能会在除夕期间运行),格式化程序会对年份进行快照,除非您添加逻辑以使缓存在年份更改时自动刷新
试验
输出
2019-04-07
2019-04-07
2019-04-07
2020-04-07
您可以使用和来提供该年的默认值
基于,可以这样做:
static LocalDate parseLoosely(String text) {
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("[uuuu-M-d][M/d/uuuu][M/d]")
.parseDefaulting(ChronoField.YEAR, Year.now().getValue())
.toFormatter();
return LocalDate.parse(text, fmt);
}
警告:不要将格式化程序缓存在静态字段中,因为如果程序可能在除夕期间运行(网络应用程序可能会在除夕期间运行),格式化程序会对年份进行快照,除非您添加逻辑以使缓存在年份更改时自动刷新
试验
输出
2019-04-07
2019-04-07
2019-04-07
2020-04-07
在C中,我将以假定2020年为结束日期,C API将处理yyyy-MM-dd和3/7格式?我不记得有这样的事情……我会查看DateTimeFormatter内部,看看它是如何进行解析的。尤其是使用java.time.format的位。ResolverStyleSMART@Sweeper当然可以尝试DateTime.Parse3/7,您将看到值为3/7/2020 12:00:00AM。我的网站99%的输入都使用yyyy-MM-dd,所以我知道它可以处理这两种格式。@user1572哦,你的意思是。。。我从来不敢让它猜到这样的格式…在C中,我会以假设2020年为结束日期,C API处理yyyy-MM-dd和3/7格式?我不记得有这样的事情……我会查看DateTimeFormatter内部,看看它是如何进行解析的。尤其是使用java.time.format的位。ResolverStyleSMART@Sweeper当然可以尝试DateTime.Parse3/7,您将看到值为3/7/2020 12:00:00AM。我的网站99%的输入都使用yyyy-MM-dd,所以我知道它可以处理这两种格式。@user1572哦,你的意思是。。。我从来不敢让它猜测这样的格式…实际上,你可以用一种没有年份的格式解析日期字符串。请参阅,它建立在底部的解决方案的基础上。@Andreas ah~parseDefaulting!在写了我的答案之后,我知道一定会有一个这样的方法,我打算在结尾添加它作为一种替代方法,但找不到该方法的名称……实际上,你可以用一种没有年份的格式解析日期字符串。请参阅,它建立在底部的解决方案的基础上。@Andreas ah~parseDefaulting!在写了我的答案后,我知道一定会有这样的方法,我打算在最后添加它作为替代方法,但找不到冰毒是什么 od被称为。。。