私は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時間を追加するだけでいいと思うが、私は上記が正しい方法だと思う。それはなぜ機能しないのですか?
を渡す必要があり、その3は、むしろ月 – xrgb
OMGよりも、4月です。私はそれを考えなかった。 javadocで確認された:グレゴリオ暦とユリウス暦の年の最初の月は、1月は0です。ありがとうございました。私の髪を引っ張っていた。 – Steve
また、ブルートフォースではなく、プログラムでタイムゾーンを処理するように努力しています。私の経験では、それは通常、払う面倒です。 – xrgb