2014-02-12 97 views
0

我似乎找不到一個很好的方法來處理來自包含任意修飾符(如「+ 3days」)的字符串的Date對象,如http://www.php.net/manual/en/datetime.formats.relative.php中所述。我在標準的Java API中找不到任何東西,也沒有在Joda-Time中找到任何東西。是否有一個Java庫可以完成php date_modify的功能?

+1

你能發佈一個你在php中做的事情的具體例子嗎?增加日子是微不足道的,並且可以在喬達 – Durandal

+1

似乎OP想要某人能夠輸入「下個星期六」或「下個月的最後一天」,而不是明確的轉變。閱讀由OP鏈接的[相關格式文檔](http://www.php.net/manual/en/datetime.formats.relative.php)。 – beerbajay

+0

剛剛發現這個,它似乎是儘可能接近它:http://stackoverflow.com/a/1268380/864358 – Phillip

回答

2

定義在文本

如果你想增加或減少由文本定義的時間跨度時移,也爲正式標準,ISO 8601。該標準定義了DurationPnYnMnDTnHnMnS的文本格式,其中P表示期間,後面跟着若干年,月,日,小時,分鐘,秒。中間的一個T分隔時間部分和日期部分。

實例:

  • P4Y = 4年
  • P1DT12H = A一天半
  • PT1H30M =一小時和半

Joda-Time圖書館將ISO 8601作爲其默認設置,包括第8是語法。 Period class在它的構造函數中接受這樣一個字符串,用ISOPeriodFormat自動解析它。

String input = "P3D"; // 3 days. Three hours would be "PT3H", as another example. 

// Get current date-time. 
DateTimeZone timeZone = DateTimeZone.forID("Pacific/Honolulu"); 
DateTime now = new DateTime(timeZone); 

// Shift from current date-time by a Period specified by ISO "Duration" string. 
// Yes, these date-time terms (period, duration, interval) are all mixed up. 
// An effort to standardize such terms is underway. But for now, get used to it and "translate". 
Period period = new Period(input); 
DateTime dateTime = now.plus(period); 

轉儲到控制檯...

System.out.println("now: " + now); 
System.out.println("period: " + period); 
System.out.println("dateTime: " + dateTime); 

運行時...

now: 2014-02-11T23:02:10.087-10:00 
period: P3D 
dateTime: 2014-02-14T23:02:10.087-10:00 

第一,最後,下一步

搜索StackOverflow上找到許多問題回答了有關使用Joda-找到月初,開始和結尾的時間f周,等等。提示:由於很少有人輸入正確的名稱,所以使用縮寫詞「joda」進行搜索,Joda-Time

某些解決方案几乎是內置的,例如訪問月份屬性並呼籲withMinimumValue()獲得月度首月。其他人則需要幾行代碼,您可以將這些代碼放入方便的方法中。

同上「下週六」等。

提示:

  • 不要忘記/忽略時區。例如,一天何時開始的定義取決於時區。
  • 別忘了區域設置。例如,一週的第一天取決於區域設置。
  • 不要忘了DateTime的時間爲
    思考整天但實際使用DateTime實例時,請記得撥打withTimeAtStartOfDay方法。忽略「午夜」相關的課程,因爲「withTimeAtStartOfDay」旨在取代它們。
1

There isDateTimeDateTime#plusDays中的類似功能。

DateTime dateTime = DateTime.now(); 
dateTime.plusDays(3); // offset for three days from **now** 

還有一個全家plus方法,如​​,plusSecondsplusYears ...

編輯:如果你想偷懶語義......那麼你必須做更多的工作。我創建了一個簡單的regex + switch語句,它將在給定語言時間範圍內執行適當的轉換。

這將是遠不如痛苦如果你要堅持公約,並採用適當的方法,而不是供應的話另一種方法,最終調用相應的方法。

以下內容僅供參考。我不推薦它,因爲存在毫秒漂移的情況(其中您可能有now().999毫秒,後來它可能是.000)。

public static DateTime shiftDate(String shift) { 
    Pattern pattern = Pattern.compile("([+-]\\d+)\\s*(millisecond[s]*|second[s]*|minute[s]*|hour[s]*|day[s]*|week[s]*|month[s]*|year[s]*)"); 
    Matcher matcher = pattern.matcher(shift); 
    if(matcher.matches()) { 
     Integer amount = Integer.valueOf(matcher.group(1)); 
     String duration = matcher.group(2); 
     DateTime now = DateTime.now(); 
     switch(duration) { 
      case "millisecond": 
      case "milliseconds": 
       return now.plusMillis(amount); 
      case "second": 
      case "seconds": 
       return now.plusSeconds(amount); 
      case "minute": 
      case "minutes": 
       return now.plusMinutes(amount); 
      case "hour": 
      case "hours": 
       return now.plusHours(amount); 
      case "day": 
      case "days": 
       return now.plusDays(amount); 
      case "week": 
      case "weeks": 
       return now.plusWeeks(amount); 
      case "month": 
      case "months": 
       return now.plusMonths(amount); 
      case "year": 
      case "years": 
       return now.plusYears(amount); 
      case "now": 
       return now; 
      default: 
       throw new IllegalArgumentException("I'm not sure how you got past the guards, but you won't get past here."); 
     } 
    } else { 
     throw new IllegalArgumentException("Invalid shift pattern: " + shift); 
    } 
} 
+0

我看到了那些,但date_modify允許您傳遞任意字符串,而不必編寫自定義分析器你自己。 – Phillip

+0

這不是OP要求的。 – beerbajay

+0

好吧,你並不是真的在編寫一個自定義的解析器,你只是在需要時調用適當的方法。 Java約定與PHP約定的工作方式不同,因爲您需要更明確地說明所調用的內容,而不僅僅是傳遞字符串來實現。 – Makoto

-1

是的。退房Joda-Time它比Java提供的更優雅。

另外請注意,Date對象的設計目的不在於這種方式。如果你想操作時態對象,你應該使用Calendar對象。日期對象不應該被操縱,雖然由於某些原因它們不是不可變的。

無論如何,得到喬達時間和你的約會問題將消失。 :)

相關問題