【问题标题】:PHP's strtotime() in JavaJava中的PHP strtotime()
【发布时间】:2013-11-08 22:37:38
【问题描述】:

php 中的strtotime() 可以做如下转换:

输入:

strtotime('2004-02-12T15:19:21+00:00'); strtotime('星期四,2000 年 12 月 21 日 16:01:07 +0200'); strtotime('1 月 1 日星期一'); strtotime('明天'); strtotime('-1 周 2 天 4 小时 2 秒');

输出:

2004-02-12 07:02:21 2000-12-21 06:12:07 2009-01-01 12:01:00 2009-02-12 12:02:00 2009-02-06 09:02:41

在java中有没有简单的方法来做到这一点?

是的,这是duplicate。但是,最初的问题没有得到回答。我通常需要能够查询过去的日期。我想让用户能够说“我想要从“-1 周”到“现在”的所有事件。这将使编写这些类型的请求的脚本变得更加容易。

【问题讨论】:

  • FWIW,我的理解是 strtotime 的工作方式与 gnu 软件(如“日期”)解释字符串日期的方式相同。相关源代码在 coreutils 的 lib/getdate.y 中。 getdate.y 定义了一个解析器,它被“编译”(不记得正确的术语)到 lib/getdate.c 中。将 c 转换为 java 对我来说似乎真的很难,但也许有人比我更聪明和/或更雄心勃勃......

标签: java php strtotime


【解决方案1】:

我尝试实现一个简单的(静态)类来模拟 PHP 的 strtotime 的一些模式。这个类被设计成开放修改(只需通过registerMatcher添加一个新的Matcher):

public final class strtotime {

    private static final List<Matcher> matchers;

    static {
        matchers = new LinkedList<Matcher>();
        matchers.add(new NowMatcher());
        matchers.add(new TomorrowMatcher());
        matchers.add(new DateFormatMatcher(new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z")));
        matchers.add(new DateFormatMatcher(new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z")));
        matchers.add(new DateFormatMatcher(new SimpleDateFormat("yyyy MM dd")));
        // add as many format as you want 
    }

    // not thread-safe
    public static void registerMatcher(Matcher matcher) {
        matchers.add(matcher);
    }

    public static interface Matcher {

        public Date tryConvert(String input);
    }

    private static class DateFormatMatcher implements Matcher {

        private final DateFormat dateFormat;

        public DateFormatMatcher(DateFormat dateFormat) {
            this.dateFormat = dateFormat;
        }

        public Date tryConvert(String input) {
            try {
                return dateFormat.parse(input);
            } catch (ParseException ex) {
                return null;
            }
        }
    }

    private static class NowMatcher implements Matcher {

        private final Pattern now = Pattern.compile("now");

        public Date tryConvert(String input) {
            if (now.matcher(input).matches()) {
                return new Date();
            } else {
                return null;
            }
        }
    }

    private static class TomorrowMatcher implements Matcher {

        private final Pattern tomorrow = Pattern.compile("tomorrow");

        public Date tryConvert(String input) {
            if (tomorrow.matcher(input).matches()) {
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.DAY_OF_YEAR, +1);
                return calendar.getTime();
            } else {
                return null;
            }
        }
    }

    public static Date strtotime(String input) {
        for (Matcher matcher : matchers) {
            Date date = matcher.tryConvert(input);

            if (date != null) {
                return date;
            }
        }

        return null;
    }

    private strtotime() {
        throw new UnsupportedOperationException();
    }
}

用法

基本用法:

 Date now = strtotime("now");
 Date tomorrow = strtotime("tomorrow");
2009 年 8 月 12 日星期三 22:18:57 CEST 2009 年 8 月 13 日星期四 22:18:57 CEST

扩展

例如让我们添加days matcher

strtotime.registerMatcher(new Matcher() {

    private final Pattern days = Pattern.compile("[\\-\\+]?\\d+ days");

    public Date tryConvert(String input) {

        if (days.matcher(input).matches()) {
            int d = Integer.parseInt(input.split(" ")[0]);
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DAY_OF_YEAR, d);
            return calendar.getTime();
        }

        return null;
    }
});

那么你可以写:

System.out.println(strtotime("3 days"));
System.out.println(strtotime("-3 days"));

(现在是Wed Aug 12 22:18:57 CEST 2009

2009 年 8 月 15 日星期六 22:18:57 CEST 2009 年 8 月 9 日星期日 22:18:57 CEST

【讨论】:

  • @dfa - 我也被否决了,因为我记得我昨晚有两票。我认为有人在横冲直撞:(
  • 这并不完全像改变Java语法,它只是一个库类
  • 我已经使用了很长时间的改编和扩展版本来了! -> github.com/wareninja/strtotime-for-java
【解决方案2】:

你可以使用简单的日期格式来做这样的事情,但是在解析字符串之前你必须知道日期格式。 PHP 会尝试猜测它,Java 期望你明确告诉他要做什么。

例子:

SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
SimpleDateFormat formater = new SimpleDateFormat("MM/dd/yy");
Date d = parser.parse("2007-04-23 11:22:02");
System.out.println(formater.format(d));

它输出:

04/23/2007

如果字符串格式不正确,SimpleDateFormat 将静默失败,除非您设置:

parser.setLenient(false);

在这种情况下,它会抛出 java.text.ParseException。

对于高级格式化,请使用 DateFormat,它有很多 operators

【讨论】:

    【解决方案3】:

    看看JodaTime,我认为这是最好的java日期时间库。

    【讨论】:

      【解决方案4】:

      使用日历并使用 SimpleDateFormat 格式化结果:

      http://java.sun.com/j2se/1.5.0/docs/api/java/util/Calendar.html

          Calendar now = Calendar.getInstance();
          Calendar working;
          SimpleDateFormat formatter = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
      
          working = (Calendar) now.clone();
      
          //strtotime("-2 years")
          working.add(Calendar.DAY_OF_YEAR, - (365 * 2));
          System.out.println("  Two years ago it was: " + formatter.format(working.getTime()));
      
          working = (Calendar) now.clone();
      
          //strtotime("+5 days");
          working.add(Calendar.DAY_OF_YEAR, + 5);
          System.out.println("  In five days it will be: " + formatter.format(working.getTime()));
      

      很好,它比 PHP 的 strtotime() 更冗长,但归根结底,它是您所追求的功能。

      【讨论】:

        【解决方案5】:

        据我所知,没有这样的东西。你必须自己破解一个。但是,这可能不是必需的。尝试将日期存储为时间戳并进行简单的数学运算。我知道这并不像你想的那么干净。但它会起作用。

        【讨论】:

        • 对,检查我的示例实现答案(随意更改实现)
        猜你喜欢
        • 1970-01-01
        • 2012-01-27
        • 2012-12-02
        • 2014-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多