public int compare(TimeZone o1, TimeZone o2) { int result = o1.getRawOffset() - o2.getRawOffset(); if (result == 0) result = o1.getDisplayName(locale).compareTo(o2.getDisplayName(locale)); return result; }
/** * Converts this <code>Date</code> object to a <code>String</code>. The output format is as * follows: * * <blockquote> * * <pre>yyyy MM dd hh mm ss +zzzz</pre> * * </blockquote> * * where: * * <ul> * <li> * <dd>yyyy is the year, as four decimal digits. Year values larger than * <dd>9999 will be truncated to * <dd>9999. * <li> * <dd>MM is the month ( * <dd>01 through * <dd>12), as two decimal digits. * <li> * <dd>dd is the day of the month ( * <dd>01 through * <dd>31), as two decimal digits. * <li> * <dd>hh is the hour of the day ( * <dd>00 through * <dd>23), as two decimal digits. * <li> * <dd>mm is the minute within the hour ( * <dd>00 through * <dd>59), as two decimal digits. * <li> * <dd>ss is the second within the minute ( * <dd>00 through * <dd>59), as two decimal digits. * <li> * <dd>zzzz is the time zone offset in hours and minutes (four decimal digits * <dd>"hhmm") relative to GMT, preceded by a "+" or "-" character ( * <dd>-1200 through * <dd>+1200). For instance, Pacific Standard Time zone is printed as * <dd>-0800. GMT is printed as * <dd>+0000. * </ul> * * @return a string representation of this date. */ public static String toISO8601String(Calendar calendar) { // Printing in the absence of a Calendar // implementation class is not supported if (calendar == null) { return "0000 00 00 00 00 00 +0000"; } int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH) + 1; int day = calendar.get(Calendar.DAY_OF_MONTH); int hour_of_day = calendar.get(Calendar.HOUR_OF_DAY); int hour = calendar.get(Calendar.HOUR); int minute = calendar.get(Calendar.MINUTE); int seconds = calendar.get(Calendar.SECOND); String yr = Integer.toString(year); // The total size of the string buffer // yr.length+1+2+1+2+1+2+1+2+1+2+1+5 = 25 + yr.length StringBuffer sb = new StringBuffer(25 + yr.length()); appendFourDigits(sb, year).append(' '); appendTwoDigits(sb, month).append(' '); appendTwoDigits(sb, day).append(' '); appendTwoDigits(sb, hour_of_day).append(' '); appendTwoDigits(sb, minute).append(' '); appendTwoDigits(sb, seconds).append(' '); // TimeZone offset is represented in milliseconds. // Convert the offset to minutes: TimeZone t = calendar.getTimeZone(); int zoneOffsetInMinutes = t.getRawOffset() / 1000 / 60; if (zoneOffsetInMinutes < 0) { zoneOffsetInMinutes = Math.abs(zoneOffsetInMinutes); sb.append('-'); } else { sb.append('+'); } int zoneHours = zoneOffsetInMinutes / 60; int zoneMinutes = zoneOffsetInMinutes % 60; appendTwoDigits(sb, zoneHours); appendTwoDigits(sb, zoneMinutes); return sb.toString(); }
private void writeTimeZone(MarkupWriter writer) { if (timeZone == TimeZoneVisibility.NONE) return; TimeZone tz = timeZoneTracker.getClientTimeZone(); writer.element("span", "class", "tx-datefield-timezone"); switch (timeZone) { case DISPLAY: writer.write(" "); writer.write(tz.getDisplayName(locale)); break; case SELECT: writer.element("select", "name", getControlName() + "$timezone"); for (TimeZone option : F.flow(TimeZone.getAvailableIDs()).map(ID_TO_TIME_ZONE).sort(timeZoneComparator)) { writer.element("option", "value", option.getID()); if (tz.equals(option)) writer.attributes("selected", "selected"); int offset = option.getRawOffset() / (1000 * 60 * 60); writer.write(String.format("UTC%+03d %s", offset, option.getID())); writer.end(); } writer.end(); default: break; } writer.end(); }
/** * Converts the milliseconds since the epoch UTC (<code>time</code>) to time fields (<code>fields * </code>). */ protected synchronized void computeFields() { boolean gregorian = (time >= gregorianCutover); TimeZone zone = getTimeZone(); fields[ZONE_OFFSET] = zone.getRawOffset(); long localTime = time + fields[ZONE_OFFSET]; long day = localTime / (24 * 60 * 60 * 1000L); int millisInDay = (int) (localTime % (24 * 60 * 60 * 1000L)); if (millisInDay < 0) { millisInDay += (24 * 60 * 60 * 1000); day--; } calculateDay(fields, day, gregorian); fields[DST_OFFSET] = zone.getOffset( fields[ERA], fields[YEAR], fields[MONTH], fields[DAY_OF_MONTH], fields[DAY_OF_WEEK], millisInDay) - fields[ZONE_OFFSET]; millisInDay += fields[DST_OFFSET]; if (millisInDay >= 24 * 60 * 60 * 1000) { millisInDay -= 24 * 60 * 60 * 1000; calculateDay(fields, ++day, gregorian); } fields[DAY_OF_WEEK_IN_MONTH] = (fields[DAY_OF_MONTH] + 6) / 7; // which day of the week are we (0..6), relative to getFirstDayOfWeek int relativeWeekday = (7 + fields[DAY_OF_WEEK] - getFirstDayOfWeek()) % 7; fields[WEEK_OF_MONTH] = (fields[DAY_OF_MONTH] - relativeWeekday + 12) / 7; int weekOfYear = (fields[DAY_OF_YEAR] - relativeWeekday + 6) / 7; // Do the Correction: getMinimalDaysInFirstWeek() is always in the // first week. int minDays = getMinimalDaysInFirstWeek(); int firstWeekday = (7 + getWeekDay(fields[YEAR], minDays) - getFirstDayOfWeek()) % 7; if (minDays - firstWeekday < 1) weekOfYear++; fields[WEEK_OF_YEAR] = weekOfYear; int hourOfDay = millisInDay / (60 * 60 * 1000); fields[AM_PM] = (hourOfDay < 12) ? AM : PM; int hour = hourOfDay % 12; fields[HOUR] = hour; fields[HOUR_OF_DAY] = hourOfDay; millisInDay %= (60 * 60 * 1000); fields[MINUTE] = millisInDay / (60 * 1000); millisInDay %= (60 * 1000); fields[SECOND] = millisInDay / (1000); fields[MILLISECOND] = millisInDay % 1000; areFieldsSet = isSet[ERA] = isSet[YEAR] = isSet[MONTH] = isSet[WEEK_OF_YEAR] = isSet[WEEK_OF_MONTH] = isSet[DAY_OF_MONTH] = isSet[DAY_OF_YEAR] = isSet[DAY_OF_WEEK] = isSet[DAY_OF_WEEK_IN_MONTH] = isSet[AM_PM] = isSet[HOUR] = isSet[HOUR_OF_DAY] = isSet[MINUTE] = isSet[SECOND] = isSet[MILLISECOND] = isSet[ZONE_OFFSET] = isSet[DST_OFFSET] = true; }
/** * Converts the time field values (<code>fields</code>) to milliseconds since the epoch UTC ( * <code>time</code>). * * @throws IllegalArgumentException if any calendar fields are invalid. */ protected synchronized void computeTime() { int millisInDay = 0; int era = fields[ERA]; int year = fields[YEAR]; int month = fields[MONTH]; int day = fields[DAY_OF_MONTH]; int minute = fields[MINUTE]; int second = fields[SECOND]; int millis = fields[MILLISECOND]; int[] month_days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int[] dayCount = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; int hour = 0; if (!isLenient()) nonLeniencyCheck(); if (!isSet[MONTH] && (!isSet[DAY_OF_WEEK] || isSet[WEEK_OF_YEAR])) { // 5: YEAR + DAY_OF_WEEK + WEEK_OF_YEAR if (isSet[WEEK_OF_YEAR]) { int first = getFirstDayOfMonth(year, 0); int offs = 1; int daysInFirstWeek = getFirstDayOfWeek() - first; if (daysInFirstWeek <= 0) daysInFirstWeek += 7; if (daysInFirstWeek < getMinimalDaysInFirstWeek()) offs += daysInFirstWeek; else offs -= 7 - daysInFirstWeek; month = 0; day = offs + 7 * (fields[WEEK_OF_YEAR] - 1); offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek(); if (offs < 0) offs += 7; day += offs; } else { // 4: YEAR + DAY_OF_YEAR month = 0; day = fields[DAY_OF_YEAR]; } } else { if (isSet[DAY_OF_WEEK]) { int first = getFirstDayOfMonth(year, month); // 3: YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK if (isSet[DAY_OF_WEEK_IN_MONTH]) { if (fields[DAY_OF_WEEK_IN_MONTH] < 0) { month++; first = getFirstDayOfMonth(year, month); day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH]); } else day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH] - 1); int offs = fields[DAY_OF_WEEK] - first; if (offs < 0) offs += 7; day += offs; } else { // 2: YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK int offs = 1; int daysInFirstWeek = getFirstDayOfWeek() - first; if (daysInFirstWeek <= 0) daysInFirstWeek += 7; if (daysInFirstWeek < getMinimalDaysInFirstWeek()) offs += daysInFirstWeek; else offs -= 7 - daysInFirstWeek; day = offs + 7 * (fields[WEEK_OF_MONTH] - 1); offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek(); if (offs <= 0) offs += 7; day += offs; } } // 1: YEAR + MONTH + DAY_OF_MONTH } if (era == BC && year > 0) year = 1 - year; // rest of code assumes day/month/year set // should negative BC years be AD? // get the hour (but no check for validity) if (isSet[HOUR]) { hour = fields[HOUR]; if (fields[AM_PM] == PM) hour += 12; } else hour = fields[HOUR_OF_DAY]; // Read the era,year,month,day fields and convert as appropriate. // Calculate number of milliseconds into the day // This takes care of both h, m, s, ms over/underflows. long allMillis = (((hour * 60L) + minute) * 60L + second) * 1000L + millis; day += allMillis / (24 * 60 * 60 * 1000L); millisInDay = (int) (allMillis % (24 * 60 * 60 * 1000L)); if (month < 0) { year += (int) month / 12; month = month % 12; if (month < 0) { month += 12; year--; } } if (month > 11) { year += (month / 12); month = month % 12; } month_days[1] = isLeapYear(year) ? 29 : 28; while (day <= 0) { if (month == 0) { year--; month_days[1] = isLeapYear(year) ? 29 : 28; } month = (month + 11) % 12; day += month_days[month]; } while (day > month_days[month]) { day -= (month_days[month]); month = (month + 1) % 12; if (month == 0) { year++; month_days[1] = isLeapYear(year) ? 29 : 28; } } // ok, by here we have valid day,month,year,era and millisinday int dayOfYear = dayCount[month] + day - 1; // (day starts on 1) if (isLeapYear(year) && month > 1) dayOfYear++; int relativeDay = (year - 1) * 365 + ((year - 1) >> 2) + dayOfYear - EPOCH_DAYS; // gregorian days from 1 to epoch. int gregFactor = (int) Math.floor((double) (year - 1) / 400.) - (int) Math.floor((double) (year - 1) / 100.); if ((relativeDay + gregFactor) * 60L * 60L * 24L * 1000L >= gregorianCutover) relativeDay += gregFactor; else relativeDay -= 2; time = relativeDay * (24 * 60 * 60 * 1000L) + millisInDay; // the epoch was a Thursday. int weekday = (int) (relativeDay + THURSDAY) % 7; if (weekday <= 0) weekday += 7; fields[DAY_OF_WEEK] = weekday; // Time zone corrections. TimeZone zone = getTimeZone(); int rawOffset = isSet[ZONE_OFFSET] ? fields[ZONE_OFFSET] : zone.getRawOffset(); int dstOffset = isSet[DST_OFFSET] ? fields[DST_OFFSET] : (zone.getOffset( (year < 0) ? BC : AD, (year < 0) ? 1 - year : year, month, day, weekday, millisInDay) - zone.getRawOffset()); time -= rawOffset + dstOffset; isTimeSet = true; }