确定模式给出的时间范围

发布于 2024-09-26 21:14:28 字数 258 浏览 7 评论 0原文

可以使用例如 SimpleDateFormat(formatPattern, locale) 来格式化日期。 是否可以以某种方式确定给定日期的 formatPattern 表示的时间段(以秒为单位)?例如,如果我们有

Date date = new Date(1286488800);
String formatPattern = "yyyy";

可能确定 formatPattern 表示的年份长度(以秒为单位)以及日期所在的位置?

A date can be formatted using a e.g. SimpleDateFormat(formatPattern, locale).
Is it somehow possible to determine the time period (in seconds) that is represented by formatPattern given a date? E.g. if we have

Date date = new Date(1286488800);
String formatPattern = "yyyy";

is it possible to determine the length of the year (in seconds) represented by formatPattern and in which date lies?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深居我梦 2024-10-03 21:14:28

我认为使用 formatPattern 来检测日期范围是一件坏事。您需要为日期模式编写一个解析器。更好的想法是使用包含可能范围(年、月、周等)的下拉列表。那么以秒为单位计算当前范围的长度就不成问题了。

I think a to use a formatPattern to detect a date range is a bad thing. You need to write a parser for the date pattern. A better idea is to use a drop down list with possible ranges (year, month, week, etc.). Then it not a problem to calculate the length of the current range in seconds.

定格我的天空 2024-10-03 21:14:28

我相信已经找到了适当的解决方案。它对我有用,尽管我不确定也没有测试这是否在每种情况下都准确有效(例如闰秒)。如果您有改进建议,请随时发布。代码如下:

public long getIntervalTimeForFormat(String formatPattern, TimeZone timezone, Locale locale, Date inputDate){
  Date someOddestDate = new Date(1318352124368L);
  GregorianCalendar calendar = new GregorianCalendar();
  calendar.setTime(someOddestDate);
  GregorianCalendar calendarInput = new GregorianCalendar();
  calendarInput.setTime(inputDate);
  Date reducedDate = null;
try {
    SimpleDateFormat formatter = new SimpleDateFormat(formatPattern, locale);
    formatter.setTimeZone(timezone);
    reducedDate = formatter.parse(formatter.format(someOddestDate));
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
  GregorianCalendar reducedCalendar = new GregorianCalendar();
  reducedCalendar.setTime(reducedDate);
  int maxField = 0;
  int i = 14;
//    System.out.println("Reduced date is "+DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.GERMAN).format(reducedDate)+" - Oddest date is "+DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.GERMAN).format(someOddestDate));
  while(i > 0 &&  maxField == 0){
//        System.out.println("Reduced Field "+i+" is set "+reducedCalendar.isSet(i)+" and has value "+reducedCalendar.get(i)+" with actual maximum "+   reducedCalendar.getActualMaximum(i)+" and minimum "+reducedCalendar.getActualMinimum(i)+"-> "+reducedCalendar.getDisplayName(i, DateFormat.FULL, Locale.UK));
//        System.out.println("Oddest date Field "+i+" is set "+calendar.isSet(i)+" and has value "+calendar.get(i)+" with actual maximum "+ calendar.getActualMaximum(i)+" and minimum "+calendar.getActualMinimum(i)+"-> "+calendar.getDisplayName(i, DateFormat.FULL, Locale.UK));
      if(reducedCalendar.get(i) == calendar.get(i)){
//            System.out.println("-------> Field "+i+" is equal.");
          maxField = i;
      }
      i--;
  }
  long valueInMillis = Long.MIN_VALUE;
  switch(maxField){
    case 1: valueInMillis = calendarInput.getActualMaximum(6) * 24L * 60 * 60 * 1000; break;// current year granularity
    case 2: valueInMillis = calendarInput.getActualMaximum(5) * 24L * 60 * 60 * 1000; break;// current month granularity
    case 3: //week in month // we just want to know that the granularity is week here and don't care about partial weeks
    case 4: valueInMillis = 7 * 24L * 60 * 60 * 1000; break; // week in year
    case 5: //day granularity
    case 6:
    case 7:
    case 8: valueInMillis = 24L * 60 * 60 * 1000; break; 
    case 9: valueInMillis = 12L * 60 * 60 * 1000; break; //half a day
    case 10: //hour
    case 11: valueInMillis = 60 * 60 * 1000; break; 
    case 12: valueInMillis = 60 * 1000; break; //minute
    case 13: valueInMillis = 1000; break; //second
    case 14: valueInMillis = 1; break; //millisecond
    default: System.err.println("This should never happen.");
  }
//    System.out.println("Returning "+valueInMillis);
return valueInMillis;

它的工作原理基本上是,将日历集的日历字段与使用所有字段 (oddestDate) 的日期进行比较,并将日历设置为相同日期,但由 formatPattern 再次格式化、打印和解析。为了至少补偿闰年,还需要 inputDate。

I believe to have found a proper solution for this. It works for me, although I am not sure and haven't tested whether this works precisely in every situtions (e.g. with leap seconds). If you have suggestions for improvement, feel free to post them. Here is the code:

public long getIntervalTimeForFormat(String formatPattern, TimeZone timezone, Locale locale, Date inputDate){
  Date someOddestDate = new Date(1318352124368L);
  GregorianCalendar calendar = new GregorianCalendar();
  calendar.setTime(someOddestDate);
  GregorianCalendar calendarInput = new GregorianCalendar();
  calendarInput.setTime(inputDate);
  Date reducedDate = null;
try {
    SimpleDateFormat formatter = new SimpleDateFormat(formatPattern, locale);
    formatter.setTimeZone(timezone);
    reducedDate = formatter.parse(formatter.format(someOddestDate));
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
  GregorianCalendar reducedCalendar = new GregorianCalendar();
  reducedCalendar.setTime(reducedDate);
  int maxField = 0;
  int i = 14;
//    System.out.println("Reduced date is "+DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.GERMAN).format(reducedDate)+" - Oddest date is "+DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.GERMAN).format(someOddestDate));
  while(i > 0 &&  maxField == 0){
//        System.out.println("Reduced Field "+i+" is set "+reducedCalendar.isSet(i)+" and has value "+reducedCalendar.get(i)+" with actual maximum "+   reducedCalendar.getActualMaximum(i)+" and minimum "+reducedCalendar.getActualMinimum(i)+"-> "+reducedCalendar.getDisplayName(i, DateFormat.FULL, Locale.UK));
//        System.out.println("Oddest date Field "+i+" is set "+calendar.isSet(i)+" and has value "+calendar.get(i)+" with actual maximum "+ calendar.getActualMaximum(i)+" and minimum "+calendar.getActualMinimum(i)+"-> "+calendar.getDisplayName(i, DateFormat.FULL, Locale.UK));
      if(reducedCalendar.get(i) == calendar.get(i)){
//            System.out.println("-------> Field "+i+" is equal.");
          maxField = i;
      }
      i--;
  }
  long valueInMillis = Long.MIN_VALUE;
  switch(maxField){
    case 1: valueInMillis = calendarInput.getActualMaximum(6) * 24L * 60 * 60 * 1000; break;// current year granularity
    case 2: valueInMillis = calendarInput.getActualMaximum(5) * 24L * 60 * 60 * 1000; break;// current month granularity
    case 3: //week in month // we just want to know that the granularity is week here and don't care about partial weeks
    case 4: valueInMillis = 7 * 24L * 60 * 60 * 1000; break; // week in year
    case 5: //day granularity
    case 6:
    case 7:
    case 8: valueInMillis = 24L * 60 * 60 * 1000; break; 
    case 9: valueInMillis = 12L * 60 * 60 * 1000; break; //half a day
    case 10: //hour
    case 11: valueInMillis = 60 * 60 * 1000; break; 
    case 12: valueInMillis = 60 * 1000; break; //minute
    case 13: valueInMillis = 1000; break; //second
    case 14: valueInMillis = 1; break; //millisecond
    default: System.err.println("This should never happen.");
  }
//    System.out.println("Returning "+valueInMillis);
return valueInMillis;

It basically works by comparing the calender fields of a calendar set to a date that uses all fields (oddestDate) with a calendar set to the same date but formatted, printed, and parsed again by the formatPattern. To compensate at least for leap years, an inputDate is also required.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文