2016-03-30 37 views
0

私はDate-likeオブジェクト(IDfTime)を与えているアプリケーションAPI(DFC)で作業しています。 APIは自動的に日付をローカルタイムゾーン(EST)に変換します。 Oracleデータベースに送信するには、UTCに変換する必要があります。何らかの理由で、私のコードが1ヶ月追加されています。私はそれを理解していない。誰もこれを説明できますか?Java日付のESTからUTCへの変換

modifyDateは、app APIによって返されるDate-likeオブジェクトです。私はそれを文字列に変換し、期待通りに見える(私にとってはEST)。したがって、CalendarとSimpleDateFormatを使用して、特定の書式設定された文字列に変換して、SQLの更新ステートメントでUTC文字列を使用してデータベースに送信できます。

注:デバッグステートメントをバッチジョブログファイルに書き込んでいますが、stdoutではなくappによって生成されます。はい、良い方法がありますが、これは素早いウィジェットであるはずです。

//adjust modify date for UTC to send to database 
String dfcDatePattern = "mm/dd/yyyy hh:mi:ss"; 
String javaDatePattern = "MM/dd/yyyy HH:mm:ss"; 
String oracleDatePattern = "MM/DD/YYYY HH24:MI:SS"; 

String strModifyDate = modifyDate.asString(dfcDatePattern); 
if (m_debugMode) m_File.writeBytes("DFC Modify Date String: " + strModifyDate + NEWLINE); 

TimeZone localTimeZone = TimeZone.getDefault(); 
TimeZone utcTimeZone = TimeZone.getTimeZone("UTC"); 
GregorianCalendar cal = new GregorianCalendar(); 
cal.setTimeZone(localTimeZone); 
if (m_debugMode) m_File.writeBytes("DFC Year: " + modifyDate.getYear() + NEWLINE); 
if (m_debugMode) m_File.writeBytes("DFC Month: " + modifyDate.getMonth() + NEWLINE); 
if (m_debugMode) m_File.writeBytes("DFC Day: " + modifyDate.getDay() + NEWLINE); 
if (m_debugMode) m_File.writeBytes("DFC Hour: " + modifyDate.getHour() + NEWLINE); 
if (m_debugMode) m_File.writeBytes("DFC Minutes: " + modifyDate.getMinutes() + NEWLINE); 
if (m_debugMode) m_File.writeBytes("DFC Seconds: " + modifyDate.getSeconds() + NEWLINE); 
cal.set(modifyDate.getYear(), modifyDate.getMonth(), modifyDate.getDay(), modifyDate.getHour(), modifyDate.getMinutes(), modifyDate.getSeconds()); 
if (m_debugMode) m_File.writeBytes("Converted Modify Date: " + cal.toString() + NEWLINE); 
SimpleDateFormat sdf = new SimpleDateFormat(javaDatePattern); 
if (m_debugMode) m_File.writeBytes("Modify Date in Local Time Zone: " + sdf.format(cal.getTime()) + NEWLINE); 
sdf.setTimeZone(utcTimeZone); 
if (m_debugMode) m_File.writeBytes("Modify Date in UTC Time Zone: " + sdf.format(cal.getTime()) + NEWLINE); 

updateQueryString = "execute exec_sql with query = 'update dm_sysobject_s set r_modify_date = TO_DATE(''" + sdf.format(cal.getTime()) + "'',''" + oracleDatePattern + "'') where r_object_id = ''" + objectIdString + "'' '"; 

出力:

DFC Modify Date String: 03/30/2016 11:44:30 [yep, looks good] 
DFC Year: 2016 
DFC Month: 3 [month looks good here] 
DFC Day: 30 
DFC Hour: 11 [EST hour] 
DFC Minutes: 44 
DFC Seconds: 30 

[うん各部分がよさそうだ]

Converted Modify Date: java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=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]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2016,MONTH=3,WEEK_OF_YEAR=14,WEEK_OF_MONTH=5,DAY_OF_MONTH=30,DAY_OF_YEAR=90,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=5,AM_PM=1,HOUR=3,HOUR_OF_DAY=11,MINUTE=44,SECOND=30,MILLISECOND=399,ZONE_OFFSET=-18000000,DST_OFFSET=3600000] 

[私は何が起こっているかを把握できたかどうかを確認するために、これをダンプされました。私はすべてがよく見えると思う]

Modify Date in Local Time Zone: 04/30/2016 11:44:30 

[いいえ!時間は正しいですが、それは1ヶ月を追加しました! UTCオフセットはわずか4時間です。]

Modify Date in UTC Time Zone: 04/30/2016 15:44:30 

[いいえ!時間は正しく調整されましたが、まだ月が追加されました]

exec_sql to update r_modify_date: execute exec_sql with query = 'update dm_sysobject_s set r_modify_date = TO_DATE(''04/30/2016 15:44:30'',''MM/DD/YYYY HH24:MI:SS'') where r_object_id = ''09ae12f980002934'' ' 

[これはSQLのように見えます。同じ日ですが、時間はUTCオフセットに合わせて調整されます。月はオフです。 SQLの構文は良いです(API構文のために奇妙に見えます)。 DB内のレコードを更新します。ちょうど間違った月です。]

ハードコーディングされたオフセットに4時間を追加するだけでいいと思うが、私は上記が正しい方法だと思う。それはなぜ機能しないのですか?

+0

を渡す必要があり、その3は、むしろ月 – xrgb

+0

OMGよりも、4月です。私はそれを考えなかった。 javadocで確認された:グレゴリオ暦とユリウス暦の年の最初の月は、1月は0です。ありがとうございました。私の髪を引っ張っていた。 – Steve

+0

また、ブルートフォースではなく、プログラムでタイムゾーンを処理するように努力しています。私の経験では、それは通常、払う面倒です。 – xrgb

答えて

0

java.util.GregorianCalendarでは、月はゼロに基づいています。月を示すために、あなたは私が月をゼロベースjava.util.GregorianCalendarのためであると考えている2ではなく3

java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=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]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2016,MONTH=2,WEEK_OF_YEAR=14,WEEK_OF_MONTH=5,DAY_OF_MONTH=30,DAY_OF_YEAR=90,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=5,AM_PM=1,HOUR=3,HOUR_OF_DAY=11,MINUTE=44,SECOND=30,MILLISECOND=399,ZONE_OFFSET=-18000000,DST_OFFSET=3600000] 
関連する問題