2016-07-14 4 views
0

次の形式で定義されているように、TimeZoneのPOSIX形式を作成する必要があります。 "アメリカ/ニューヨーク" のEXについてJava TimeZoneとLinux TimeZone夏時間が一致しない

std offset dst [offset],start[/time],end[/time] 

POSIX形式は値M3.2.0/2で表され EST + 5EDT、M3.2.0/2、M11.1.0/2ここで

ありますMm.wd/tの形式。

これは、月の月のm日を指定します。日dは0(日曜日)〜6日の間でなければなりません。週wは1〜5でなければなりません。週1は、日dが発生する最初の週であり、週5は、月の最後の日を指定します。月mは1と12の間、私は次のリンク

http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html

したがって、上記の例の状態、UTCからのオフセット正常から上記の説明は5時間で借りなければなりません。これは本来の子午線の西側であるため、符号は正である。夏時間は3月の第2日曜日の午前2時に開始し、11月の第1日曜日の午前2時に終了します。

私は、Linuxのタイムゾーンファイルを/ usr/share/zoneinfoの/アメリカ/ニューヨークでこれをチェックすると、私はこれを構築するとき、それはしかし

EST5EDT、M3.2.0、M11.1.0

上記の値と一致しましたタイムゾーン "アメリカ/ニューヨーク" のためのJavaで私は、次の文字列

EST-5EDT + 1、M2.1.1/2、M10.1.1/2

を取得し、私はから情報を抽出することにより、上記の文字列を構築次のコードの出力。

TimeZone timezone = TimeZone.getTimeZone("America/New_York"); 
System.out.println(timezone.toString()); 

出力

sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0] 

注意以下の通りであるLinuxの出力と比較して11であるべき値endMonth = 10。

+0

この形式のPOSIX文書へのリンクを投稿できますか?気になります。 –

+0

はい、私は説明でそれを次のように述べました http://www.gnu.org/software/libc/manual/html_node/TZ-Variable。html –

+0

ありがとうございますが、それは公式のPOSIXのドキュメントではありません。これはgnu.orgのライブラリです。グーグルでは、この想定されているPOSIXの日付/時刻形式の別の定義を文書化した他の情報源につながった。だから私は誰かが権威ある情報源を投稿することを望んでいた。 –

答えて

0

出力形式がtoStringの場合は、TimeZoneクラスまたはSimpleTimeZoneクラスのいずれの形式でも、その形式についての契約上の保証はないため、お勧めできません。

明らかに、月の数字は1つオフです。月の最初の1週間を考慮する必要があるので、今月の週はそれほど単純ではありません。

私が情報を取得するには、Javaの文書パブリックメソッドを使用します。続いて

static String posixSpecFor(TimeZone tz) { 
    Formatter posixSpec = new Formatter(); 

    float offset = (float) tz.getRawOffset()/(1000 * 60 * 60) * -1; 
    posixSpec.format("%s%s%s", 
     tz.getDisplayName(false, TimeZone.SHORT), 
     offset >= 0 ? "+" : "", 
     new DecimalFormat("0.##").format(offset)); 

    if (tz.observesDaylightTime()) { 
     posixSpec.format("%s", tz.getDisplayName(true, TimeZone.SHORT)); 
    } 

    ZoneId zone = tz.toZoneId(); 

    TemporalField weekOfMonth = 
     WeekFields.of(DayOfWeek.SUNDAY, 7).weekOfMonth(); 
    int thisYear = Year.now(zone).getValue(); 

    List<ZoneOffsetTransitionRule> rules = 
     zone.getRules().getTransitionRules(); 
    if (rules.size() > 2) { 
     rules = rules.subList(0, 2); 
    } 

    for (ZoneOffsetTransitionRule rule : rules) { 
     posixSpec.format(",M%d.%d.%d/%s", 
      rule.getMonth().getValue(), 
      rule.createTransition(thisYear).getDateTimeBefore().get(
       weekOfMonth), 
      rule.getDayOfWeek().getValue() % 7, 
      rule.getLocalTime()); 
    } 

    return posixSpec.toString(); 
} 
+0

素晴らしい!!!!私はあなたのコードからの入力を使用し、以下の文字列を構築することができました EST + 5EDT、M3.2.0/2、M11.1.0/2 あなたの助けにたくさんのThanx。 –

0

は、私はパブリッククラスPosixTimeZone {

public String toPosixTZ(String timezoneStr) { 

    TimeZone timezone = TimeZone.getTimeZone(timezoneStr); 
    sop("timezoneStr", timezoneStr); 
    String posixTX = ""; 

    PosixTimeZoneData pTZData = new PosixTimeZoneData(timezone); 
    if (timezone.useDaylightTime()) { 
     posixTX = getPosixDSString(pTZData); 
    } else { 
     posixTX = getPosixString(pTZData); 
    } 
    return posixTX; 
} 

public static void main(String args[]) { 

    System.out.println("Posix TimeZone is " + new PosixTimeZone().toPosixTZ(args[0])); 
} 

private void sop(String varname, String meesage) { 
    System.out.println("**************: " + varname + " = " + meesage); 
} 

private String getPosixDSString(PosixTimeZoneData pTZData) { 
    String posixString = ""; 

    if ((pTZData.std != null && !pTZData.std.isEmpty()) 
      && (pTZData.stdOffset != null)//&& !pTZData.stdOffset.isEmpty()) 
      && (pTZData.dst != null && !pTZData.dst.isEmpty()) 
      && (pTZData.dstOffset != null)// && !pTZData.dstOffset.isEmpty()) 
      && (pTZData.start != null && !pTZData.start.isEmpty()) 
      && (pTZData.end != null && !pTZData.end.isEmpty())) { 
     posixString = String.format("%s%s%s%s,%s,%s", pTZData.std, pTZData.stdOffset, pTZData.dst, 
       pTZData.dstOffset, pTZData.start, pTZData.end); 
    } else { 
     sop("Error", "Invalid Parameters"); 
    } 

    return posixString; 
} 

private String getPosixString(PosixTimeZoneData pTZData) { 
    String posixString = ""; 

    if ((pTZData.std != null && !pTZData.std.isEmpty()) 
      && (pTZData.stdOffset != null && !pTZData.stdOffset.isEmpty())) { 
     posixString = String.format("%s%s", pTZData.std, pTZData.stdOffset); 
    } else { 
     sop("Error", "Invalid Parameters"); 
    } 

    return posixString; 
} 

class PosixTimeZoneData { 

    String std = ""; 
    String stdOffset = ""; 
    String dst = ""; 
    String dstOffset = ""; 
    String start = ""; 
    String end = ""; 

    private PosixTimeZoneData(TimeZone timeZone) { 

     std = timeZone.getDisplayName(false, TimeZone.SHORT); 
     int rawOffset = (timeZone.getRawOffset()/3600000) * -1; 
     stdOffset = (rawOffset >= 0) 
       ? ((rawOffset == 0) || (rawOffset == 1) ? "" : "+" + rawOffset) 
       : "" + rawOffset; 
     if (timeZone.useDaylightTime()) { 
      dst = timeZone.getDisplayName(true, TimeZone.SHORT); 

      int dstRawOffset = timeZone.getDSTSavings()/3600000; 
      dstOffset = (dstRawOffset >= 0) 
        ? ((dstRawOffset == 0) || (dstRawOffset == 1) ? "" : "+" + dstRawOffset) 
        : "" + dstRawOffset; 

      ZoneId zone = timeZone.toZoneId(); 

      TemporalField weekOfMonth 
        = WeekFields.of(DayOfWeek.SUNDAY, 7).weekOfMonth(); 
      int thisYear = Year.now(zone).getValue(); 

      List<ZoneOffsetTransitionRule> rules 
        = zone.getRules().getTransitionRules(); 
      if (rules != null && !rules.isEmpty()) { 
       if (rules.size() > 2) { 
        rules = rules.subList(0, 2); 
       } 

       start = String.format("M%d.%d.%d/%s", 
         rules.get(0).getMonth().getValue(), 
         rules.get(0).createTransition(thisYear).getDateTimeBefore().get(
         weekOfMonth), 
         rules.get(0).getDayOfWeek().getValue() % 7, 
         rules.get(0).getLocalTime().getHour()); 

       end = String.format("M%d.%d.%d/%s", 
         rules.get(1).getMonth().getValue(), 
         rules.get(1).createTransition(thisYear).getDateTimeBefore().get(
         weekOfMonth), 
         rules.get(1).getDayOfWeek().getValue() % 7, 
         rules.get(1).getLocalTime().getHour()); 

      } 
     } 
    } 

} 
Posixのタイムゾーンの文字列を構築するために

を使用しています完全なコードです

}

+0

'rules'がnullかどうかを確認する必要はありません。 [メソッドの契約](https://docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html#getTransitionRules--)は、「移行ルールの不変のリスト」を返し、 nullではありません。 " – VGR

+0

それを変更します。 〜 –