private static Date parseETagForTimestamp(String etag) throws UnsupportedEncodingException { // must handle both weak and strong ETags if (etag.startsWith("W/")) { etag = etag.substring(2); } // remove etag prefix and '" suffix etag = etag.substring(TableConstants.ETAG_PREFIX.length(), etag.length() - 2); etag = URLDecoder.decode(etag, Constants.UTF8_CHARSET); return Utility.parseDate(etag); } }
private static Date parseETagForTimestamp(String etag) throws UnsupportedEncodingException { // must handle both weak and strong ETags if (etag.startsWith("W/")) { etag = etag.substring(2); } // remove etag prefix and '" suffix etag = etag.substring(TableConstants.ETAG_PREFIX.length(), etag.length() - 2); etag = URLDecoder.decode(etag, Constants.UTF8_CHARSET); return Utility.parseDate(etag); } }
/** * Gets the value of this {@link EntityProperty} as a <code>java.util.Date</code>. * * @return * A <code>java.util.Date</code> representation of the {@link EntityProperty} value, or <code>null</code>. * * @throws IllegalArgumentException * If the value is not <code>null</code> and cannot be parsed as a <code>java.util.Date</code>. */ public Date getValueAsDate() { return this.getIsNull() ? null : Utility.parseDate(this.value, this.dateBackwardCompatibility); }
/** * Gets the value of this {@link EntityProperty} as a <code>java.util.Date</code>. * * @return * A <code>java.util.Date</code> representation of the {@link EntityProperty} value, or <code>null</code>. * * @throws IllegalArgumentException * If the value is not <code>null</code> and cannot be parsed as a <code>java.util.Date</code>. */ public Date getValueAsDate() { return this.getIsNull() ? null : Utility.parseDate(this.value, this.dateBackwardCompatibility); }
/** * Given a String representing a date in a form of the ISO8601 pattern, generates a Date representing it * with up to millisecond precision. Use {@link #parseDate(String)} instead unless * <code>dateBackwardCompatibility</code> is needed. * <p> * See <a href="http://go.microsoft.com/fwlink/?LinkId=523753">here</a> for more details. * * @param dateString * the <code>String</code> to be interpreted as a <code>Date</code> * @param dateBackwardCompatibility * <code>true</code> to correct Date values that may have been written * using versions of this library prior to 0.4.0; otherwise, <code>false</code> * * @return the corresponding <code>Date</code> object */ public static Date parseDate(String dateString, boolean dateBackwardCompatibility) { if (!dateBackwardCompatibility) { return parseDate(dateString); } final int beginMilliIndex = 20; // Length of "yyyy-MM-ddTHH:mm:ss." final int endTenthMilliIndex = 24; // Length of "yyyy-MM-ddTHH:mm:ss.SSSS" // Check whether the millisecond and tenth of a millisecond digits are all 0. if (dateString.length() > endTenthMilliIndex && "0000".equals(dateString.substring(beginMilliIndex, endTenthMilliIndex))) { // Remove the millisecond and tenth of a millisecond digits. // Treat the final three digits (ticks) as milliseconds. dateString = dateString.substring(0, beginMilliIndex) + dateString.substring(endTenthMilliIndex); } return parseDate(dateString); }
/** * Given a String representing a date in a form of the ISO8601 pattern, generates a Date representing it * with up to millisecond precision. Use {@link #parseDate(String)} instead unless * <code>dateBackwardCompatibility</code> is needed. * <p> * See <a href="http://go.microsoft.com/fwlink/?LinkId=523753">here</a> for more details. * * @param dateString * the <code>String</code> to be interpreted as a <code>Date</code> * @param dateBackwardCompatibility * <code>true</code> to correct Date values that may have been written * using versions of this library prior to 2.0.0; otherwise, <code>false</code> * * @return the corresponding <code>Date</code> object */ public static Date parseDate(String dateString, boolean dateBackwardCompatibility) { if (!dateBackwardCompatibility) { return parseDate(dateString); } final int beginMilliIndex = 20; // Length of "yyyy-MM-ddTHH:mm:ss." final int endTenthMilliIndex = 24; // Length of "yyyy-MM-ddTHH:mm:ss.SSSS" // Check whether the millisecond and tenth of a millisecond digits are all 0. if (dateString.length() > endTenthMilliIndex && "0000".equals(dateString.substring(beginMilliIndex, endTenthMilliIndex))) { // Remove the millisecond and tenth of a millisecond digits. // Treat the final three digits (ticks) as milliseconds. dateString = dateString.substring(0, beginMilliIndex) + dateString.substring(endTenthMilliIndex); } return parseDate(dateString); }
@Test public void testDateStringParsingWithRounding() throws ParseException { String fullDateString = "1999-12-31T23:59:45.1234567Z"; SimpleDateFormat testFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z"); Date milliDate = testFormat.parse("1999-12-31T23:59:45.123 -0000"); assertEquals(milliDate, Utility.parseDate(fullDateString)); fullDateString = "1999-04-30T23:59:55.9876Z"; long millisSinceEpoch = 925516795987L; Date deciDate = Utility.parseDate(fullDateString.replace("876Z", "Z")); assertEquals(deciDate.getTime(), (millisSinceEpoch / 100) * 100); Date centiDate = Utility.parseDate(fullDateString.replace("76Z", "Z")); assertEquals(centiDate.getTime(), (millisSinceEpoch / 10) * 10); milliDate = Utility.parseDate(fullDateString); assertEquals(milliDate.getTime(), millisSinceEpoch); }
@Test public void testDateStringFormatting() { String fullDateString = "2014-12-07T09:15:12.123Z"; String outDateString = Utility.getJavaISO8601Time(Utility.parseDate(fullDateString)); assertEquals(fullDateString, outDateString); fullDateString = "2015-01-14T14:53:32.800Z"; outDateString = Utility.getJavaISO8601Time(Utility.parseDate(fullDateString)); assertEquals(fullDateString, outDateString); // Ensure that trimming of trailing zeroes by the service does not affect this fullDateString = "2015-01-14T14:53:32.8Z"; outDateString = Utility.getJavaISO8601Time(Utility.parseDate(fullDateString)); fullDateString = fullDateString.replace("Z", "00Z"); assertEquals(fullDateString, outDateString); // Ensure that trimming of trailing zeroes by the service does not affect this // even with dateBackwardCompatibility fullDateString = "2015-01-14T14:53:32.0000800Z"; outDateString = Utility.getJavaISO8601Time(Utility.parseDate(fullDateString, true)); fullDateString = "2015-01-14T14:53:32.800Z"; assertEquals(fullDateString, outDateString); }
private static void testDate(final String dateString, final long intendedMilliseconds, final int ticks, final boolean writtenPre2, final boolean dateBackwardCompatibility) { assertTrue(ticks >= 0); // ticks is non-negative assertTrue(ticks <= 9999); // ticks do not overflow into milliseconds long expectedMilliseconds = intendedMilliseconds; if (dateBackwardCompatibility && (intendedMilliseconds % 1000 == 0) && (ticks < 1000)) { // when no milliseconds are present dateBackwardCompatibility causes up to 3 digits of ticks // to be read as milliseconds expectedMilliseconds += ticks; } else if (writtenPre2 && !dateBackwardCompatibility && (ticks == 0)) { // without DateBackwardCompatibility, milliseconds stored by Java prior to 0.4.0 are lost expectedMilliseconds -= expectedMilliseconds % 1000; } assertEquals(expectedMilliseconds, Utility.parseDate(dateString, dateBackwardCompatibility).getTime()); }