19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.text.format; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Locale; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TimeZone; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 244af85345e798c37ab026e93a1ae250d8bca4fc40Elliott Hughesimport libcore.icu.LocaleData; 254af85345e798c37ab026e93a1ae250d8bca4fc40Elliott Hughes 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 2731e04656e77a881960daa7a6974e8f805d9cef43Scott Main * An alternative to the {@link java.util.Calendar} and 2831e04656e77a881960daa7a6974e8f805d9cef43Scott Main * {@link java.util.GregorianCalendar} classes. An instance of the Time class represents 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a moment in time, specified with second precision. It is modelled after 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * struct tm, and in fact, uses struct tm to implement most of the 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * functionality. 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Time { 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String Y_M_D_T_H_M_S_000 = "%Y-%m-%dT%H:%M:%S.000"; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String Y_M_D_T_H_M_S_000_Z = "%Y-%m-%dT%H:%M:%S.000Z"; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String Y_M_D = "%Y-%m-%d"; 370df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TIMEZONE_UTC = "UTC"; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The Julian day of the epoch, that is, January 1, 1970 on the Gregorian 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * calendar. 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int EPOCH_JULIAN_DAY = 2440588; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * The Julian day of the Monday in the week of the epoch, December 29, 1969 4850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * on the Gregorian calendar. 4950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 5050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public static final int MONDAY_BEFORE_JULIAN_EPOCH = EPOCH_JULIAN_DAY - 3; 5150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 5250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * True if this is an allDay event. The hour, minute, second fields are 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * all zero, and the date is displayed the same in all time zones. 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean allDay; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Seconds [0-61] (2 leap seconds allowed) 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int second; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Minute [0-59] 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int minute; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Hour of day [0-23] 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int hour; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Day of month [1-31] 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int monthDay; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Month [0-11] 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int month; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8431e04656e77a881960daa7a6974e8f805d9cef43Scott Main * Year. For example, 1970. 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int year; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Day of week [0-6] 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int weekDay; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Day of year [0-365] 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int yearDay; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This time is in daylight savings time. One of: 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><b>positive</b> - in dst</li> 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><b>0</b> - not in dst</li> 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><b>negative</b> - unknown</li> 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int isDst; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Offset from UTC (in seconds). 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long gmtoff; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The timezone for this Time. Should not be null. 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String timezone; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Define symbolic constants for accessing the fields in this class. Used in 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * getActualMaximum(). 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SECOND = 1; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MINUTE = 2; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int HOUR = 3; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MONTH_DAY = 4; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MONTH = 5; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int YEAR = 6; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int WEEK_DAY = 7; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int YEAR_DAY = 8; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int WEEK_NUM = 9; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SUNDAY = 0; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MONDAY = 1; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int TUESDAY = 2; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int WEDNESDAY = 3; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int THURSDAY = 4; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int FRIDAY = 5; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SATURDAY = 6; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The Locale for which date formatting strings have been loaded. 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static Locale sLocale; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String[] sShortMonths; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String[] sLongMonths; 1465bd644caf73e76750feef1a82b8817d32f5367fcEric Fischer private static String[] sLongStandaloneMonths; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String[] sShortWeekdays; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String[] sLongWeekdays; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String sTimeOnlyFormat; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String sDateOnlyFormat; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String sDateTimeFormat; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String sAm; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String sPm; 1546323b6c61775992e400c2d38981332583107c32bElliott Hughes private static char sZeroDigit; 155315a7c0335fb54beced23b1703c10563ce02ee82Roozbeh Pournader 156315a7c0335fb54beced23b1703c10563ce02ee82Roozbeh Pournader // Referenced by native code. 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String sDateCommand = "%a %b %e %H:%M:%S %Z %Y"; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Construct a Time object in the timezone named by the string 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argument "timezone". The time is initialized to Jan 1, 1970. 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param timezone string containing the timezone to use. 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see TimeZone 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Time(String timezone) { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (timezone == null) { 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new NullPointerException("timezone is null!"); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.timezone = timezone; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.year = 1970; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.monthDay = 1; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set the daylight-saving indicator to the unknown value -1 so that 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // it will be recomputed. 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.isDst = -1; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Construct a Time object in the default timezone. The time is initialized to 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Jan 1, 1970. 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Time() { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(TimeZone.getDefault().getID()); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1840df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A copy constructor. Construct a Time object by copying the given 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Time object. No normalization occurs. 1880df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param other 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Time(Time other) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set(other); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Ensures the values in each field are in range. For example if the 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current value of this calendar is March 32, normalize() will convert it 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to April 1. It also fills in weekDay, yearDay, isDst and gmtoff. 1990df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If "ignoreDst" is true, then this method sets the "isDst" field to -1 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (the "unknown" value) before normalizing. It then computes the 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * correct value for "isDst". 2040df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link #toMillis(boolean)} for more information about when to 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use <tt>true</tt> or <tt>false</tt> for "ignoreDst". 2080df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 2090df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * @return the UTC milliseconds since the epoch 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native public long normalize(boolean ignoreDst); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convert this time object so the time represented remains the same, but is 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instead located in a different timezone. This method automatically calls 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * normalize() in some cases 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native public void switchTimezone(String timezone); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int[] DAYS_PER_MONTH = { 31, 28, 31, 30, 31, 30, 31, 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31, 30, 31, 30, 31 }; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the maximum possible value for the given field given the value of 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the other fields. Requires that it be normalized for MONTH_DAY and 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * YEAR_DAY. 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param field one of the constants for HOUR, MINUTE, SECOND, etc. 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the maximum value for the field. 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getActualMaximum(int field) { 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (field) { 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SECOND: 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 59; // leap seconds, bah humbug 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MINUTE: 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 59; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case HOUR: 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 23; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MONTH_DAY: { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = DAYS_PER_MONTH[this.month]; 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != 28) { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return n; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y = this.year; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0)) ? 29 : 28; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MONTH: 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 11; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case YEAR: 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 2037; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WEEK_DAY: 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 6; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case YEAR_DAY: { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y = this.year; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Year days are numbered from 0, so the last one is usually 364. 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0)) ? 365 : 364; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WEEK_NUM: 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("WEEK_NUM not implemented"); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("bad field=" + field); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Clears all values, setting the timezone to the given timezone. Sets isDst 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to a negative value to mean "unknown". 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param timezone the timezone to use. 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clear(String timezone) { 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (timezone == null) { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new NullPointerException("timezone is null!"); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.timezone = timezone; 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.allDay = false; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.second = 0; 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.minute = 0; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.hour = 0; 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.monthDay = 0; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.month = 0; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.year = 0; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.weekDay = 0; 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.yearDay = 0; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.gmtoff = 0; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.isDst = -1; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 289467cabe879cb58df96f6a84879f5fb226e049aebKenny Root * Compare two {@code Time} objects and return a negative number if {@code 290467cabe879cb58df96f6a84879f5fb226e049aebKenny Root * a} is less than {@code b}, a positive number if {@code a} is greater than 291467cabe879cb58df96f6a84879f5fb226e049aebKenny Root * {@code b}, or 0 if they are equal. 292467cabe879cb58df96f6a84879f5fb226e049aebKenny Root * 293467cabe879cb58df96f6a84879f5fb226e049aebKenny Root * @param a first {@code Time} instance to compare 294467cabe879cb58df96f6a84879f5fb226e049aebKenny Root * @param b second {@code Time} instance to compare 295467cabe879cb58df96f6a84879f5fb226e049aebKenny Root * @throws NullPointerException if either argument is {@code null} 296467cabe879cb58df96f6a84879f5fb226e049aebKenny Root * @throws IllegalArgumentException if {@link #allDay} is true but {@code 297467cabe879cb58df96f6a84879f5fb226e049aebKenny Root * hour}, {@code minute}, and {@code second} are not 0. 298467cabe879cb58df96f6a84879f5fb226e049aebKenny Root * @return a negative result if {@code a} is earlier, a positive result if 299467cabe879cb58df96f6a84879f5fb226e049aebKenny Root * {@code a} is earlier, or 0 if they are equal. 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 301467cabe879cb58df96f6a84879f5fb226e049aebKenny Root public static int compare(Time a, Time b) { 302467cabe879cb58df96f6a84879f5fb226e049aebKenny Root if (a == null) { 303467cabe879cb58df96f6a84879f5fb226e049aebKenny Root throw new NullPointerException("a == null"); 304467cabe879cb58df96f6a84879f5fb226e049aebKenny Root } else if (b == null) { 305467cabe879cb58df96f6a84879f5fb226e049aebKenny Root throw new NullPointerException("b == null"); 306467cabe879cb58df96f6a84879f5fb226e049aebKenny Root } 307467cabe879cb58df96f6a84879f5fb226e049aebKenny Root 308467cabe879cb58df96f6a84879f5fb226e049aebKenny Root return nativeCompare(a, b); 309467cabe879cb58df96f6a84879f5fb226e049aebKenny Root } 310467cabe879cb58df96f6a84879f5fb226e049aebKenny Root 311467cabe879cb58df96f6a84879f5fb226e049aebKenny Root private static native int nativeCompare(Time a, Time b); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Print the current value given the format string provided. See man 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * strftime for what means what. The final string must be less than 256 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * characters. 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param format a string containing the desired format. 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a String containing the current time expressed in the current locale. 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String format(String format) { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (Time.class) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Locale locale = Locale.getDefault(); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sLocale == null || locale == null || !(locale.equals(sLocale))) { 32508153ee01e6aa67061f628bc3fed66c6400dfd1cElliott Hughes LocaleData localeData = LocaleData.get(locale); 32608153ee01e6aa67061f628bc3fed66c6400dfd1cElliott Hughes 32708153ee01e6aa67061f628bc3fed66c6400dfd1cElliott Hughes sAm = localeData.amPm[0]; 32808153ee01e6aa67061f628bc3fed66c6400dfd1cElliott Hughes sPm = localeData.amPm[1]; 3296323b6c61775992e400c2d38981332583107c32bElliott Hughes sZeroDigit = localeData.zeroDigit; 33008153ee01e6aa67061f628bc3fed66c6400dfd1cElliott Hughes 33108153ee01e6aa67061f628bc3fed66c6400dfd1cElliott Hughes sShortMonths = localeData.shortMonthNames; 33208153ee01e6aa67061f628bc3fed66c6400dfd1cElliott Hughes sLongMonths = localeData.longMonthNames; 33308153ee01e6aa67061f628bc3fed66c6400dfd1cElliott Hughes sLongStandaloneMonths = localeData.longStandAloneMonthNames; 33408153ee01e6aa67061f628bc3fed66c6400dfd1cElliott Hughes sShortWeekdays = localeData.shortWeekdayNames; 33508153ee01e6aa67061f628bc3fed66c6400dfd1cElliott Hughes sLongWeekdays = localeData.longWeekdayNames; 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33708153ee01e6aa67061f628bc3fed66c6400dfd1cElliott Hughes Resources r = Resources.getSystem(); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sTimeOnlyFormat = r.getString(com.android.internal.R.string.time_of_day); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sDateOnlyFormat = r.getString(com.android.internal.R.string.month_day_year); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sDateTimeFormat = r.getString(com.android.internal.R.string.date_and_time); 3414af85345e798c37ab026e93a1ae250d8bca4fc40Elliott Hughes 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sLocale = locale; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3456323b6c61775992e400c2d38981332583107c32bElliott Hughes String result = format1(format); 3466323b6c61775992e400c2d38981332583107c32bElliott Hughes if (sZeroDigit != '0') { 3476323b6c61775992e400c2d38981332583107c32bElliott Hughes result = localizeDigits(result); 3486323b6c61775992e400c2d38981332583107c32bElliott Hughes } 3496323b6c61775992e400c2d38981332583107c32bElliott Hughes return result; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native private String format1(String format); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3556323b6c61775992e400c2d38981332583107c32bElliott Hughes // TODO: unify this with java.util.Formatter's copy. 3566323b6c61775992e400c2d38981332583107c32bElliott Hughes private String localizeDigits(String s) { 3576323b6c61775992e400c2d38981332583107c32bElliott Hughes int length = s.length(); 3586323b6c61775992e400c2d38981332583107c32bElliott Hughes int offsetToLocalizedDigits = sZeroDigit - '0'; 3596323b6c61775992e400c2d38981332583107c32bElliott Hughes StringBuilder result = new StringBuilder(length); 3606323b6c61775992e400c2d38981332583107c32bElliott Hughes for (int i = 0; i < length; ++i) { 3616323b6c61775992e400c2d38981332583107c32bElliott Hughes char ch = s.charAt(i); 3626323b6c61775992e400c2d38981332583107c32bElliott Hughes if (ch >= '0' && ch <= '9') { 3636323b6c61775992e400c2d38981332583107c32bElliott Hughes ch += offsetToLocalizedDigits; 3646323b6c61775992e400c2d38981332583107c32bElliott Hughes } 3656323b6c61775992e400c2d38981332583107c32bElliott Hughes result.append(ch); 3666323b6c61775992e400c2d38981332583107c32bElliott Hughes } 3676323b6c61775992e400c2d38981332583107c32bElliott Hughes return result.toString(); 3686323b6c61775992e400c2d38981332583107c32bElliott Hughes } 3696323b6c61775992e400c2d38981332583107c32bElliott Hughes 3706323b6c61775992e400c2d38981332583107c32bElliott Hughes 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the current time in YYYYMMDDTHHMMSS<tz> format 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native public String toString(); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Parses a date-time string in either the RFC 2445 format or an abbreviated 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * format that does not include the "time" field. For example, all of the 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * following strings are valid: 3810df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>"20081013T160000Z"</li> 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>"20081013T160000"</li> 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>"20081013"</li> 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3870df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns whether or not the time is in UTC (ends with Z). If the string 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ends with "Z" then the timezone is set to UTC. If the date-time string 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * included only a date and no time field, then the <code>allDay</code> 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * field of this Time class is set to true and the <code>hour</code>, 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>minute</code>, and <code>second</code> fields are set to zero; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise (a time field was included in the date-time string) 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>allDay</code> is set to false. The fields <code>weekDay</code>, 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>yearDay</code>, and <code>gmtoff</code> are always set to zero, 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and the field <code>isDst</code> is set to -1 (unknown). To set those 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fields, call {@link #normalize(boolean)} after parsing. 3980df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To parse a date-time string and convert it to UTC milliseconds, do 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * something like this: 4010df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Time time = new Time(); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * String date = "20081013T160000Z"; 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * time.parse(date); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * long millis = time.normalize(false); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre> 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param s the string to parse 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the resulting time value is in UTC time 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws android.util.TimeFormatException if s cannot be parsed. 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean parse(String s) { 4145ef49427b6e735ba17d96184ac2bcbcafb434d82Elliott Hughes if (s == null) { 4155ef49427b6e735ba17d96184ac2bcbcafb434d82Elliott Hughes throw new NullPointerException("time string is null"); 4165ef49427b6e735ba17d96184ac2bcbcafb434d82Elliott Hughes } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nativeParse(s)) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project timezone = TIMEZONE_UTC; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Parse a time in the current zone in YYYYMMDDTHHMMSS format. 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native private boolean nativeParse(String s); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Parse a time in RFC 3339 format. This method also parses simple dates 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (that is, strings that contain no time or time offset). For example, 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * all of the following strings are valid: 4330df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>"2008-10-13T16:00:00.000Z"</li> 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>"2008-10-13T16:00:00.000+07:00"</li> 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>"2008-10-13T16:00:00.000-07:00"</li> 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>"2008-10-13"</li> 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4400df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the string contains a time and time offset, then the time offset will 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be used to convert the time value to UTC. 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 4450df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the given string contains just a date (with no time field), then 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #allDay} field is set to true and the {@link #hour}, 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #minute}, and {@link #second} fields are set to zero. 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 4510df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the resulting time value is in UTC time. 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param s the string to parse 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the resulting time value is in UTC time 458670bf11fcf9e0a73007b9b814069aa575a872096Ken Shirriff * @throws android.util.TimeFormatException if s cannot be parsed. 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean parse3339(String s) { 46111afa8a466be7fd0bb486b36612d656a09f88f46Alon Albert if (s == null) { 46211afa8a466be7fd0bb486b36612d656a09f88f46Alon Albert throw new NullPointerException("time string is null"); 46311afa8a466be7fd0bb486b36612d656a09f88f46Alon Albert } 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nativeParse3339(s)) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project timezone = TIMEZONE_UTC; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4700df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native private boolean nativeParse3339(String s); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the timezone string that is currently set for the device. 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static String getCurrentTimezone() { 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TimeZone.getDefault().getID(); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the time of the given Time object to the current time. 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native public void setToNow(); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Converts this time to milliseconds. Suitable for interacting with the 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * standard java libraries. The time is in UTC milliseconds since the epoch. 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This does an implicit normalization to compute the milliseconds but does 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <em>not</em> change any of the fields in this Time object. If you want 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to normalize the fields in this Time object and also get the milliseconds 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * then use {@link #normalize(boolean)}. 4920df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If "ignoreDst" is false, then this method uses the current setting of the 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "isDst" field and will adjust the returned time if the "isDst" field is 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * wrong for the given time. See the sample code below for an example of 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this. 4980df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If "ignoreDst" is true, then this method ignores the current setting of 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the "isDst" field in this Time object and will instead figure out the 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * correct value of "isDst" (as best it can) from the fields in this 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Time object. The only case where this method cannot figure out the 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * correct value of the "isDst" field is when the time is inherently 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ambiguous because it falls in the hour that is repeated when switching 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * from Daylight-Saving Time to Standard Time. 5070df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Here is an example where <tt>toMillis(true)</tt> adjusts the time, 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * assuming that DST changes at 2am on Sunday, Nov 4, 2007. 5110df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Time time = new Time(); 5140df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * time.set(4, 10, 2007); // set the date to Nov 4, 2007, 12am 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * time.normalize(); // this sets isDst = 1 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * time.monthDay += 1; // changes the date to Nov 5, 2007, 12am 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * millis = time.toMillis(false); // millis is Nov 4, 2007, 11pm 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * millis = time.toMillis(true); // millis is Nov 5, 2007, 12am 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre> 5200df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To avoid this problem, use <tt>toMillis(true)</tt> 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * after adding or subtracting days or explicitly setting the "monthDay" 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * field. On the other hand, if you are adding 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or subtracting hours or minutes, then you should use 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tt>toMillis(false)</tt>. 5270df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You should also use <tt>toMillis(false)</tt> if you want 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to read back the same milliseconds that you set with {@link #set(long)} 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #set(Time)} or after parsing a date string. 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native public long toMillis(boolean ignoreDst); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the fields in this Time object given the UTC milliseconds. After 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this method returns, all the fields are normalized. 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This also sets the "isDst" field to the correct value. 5390df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param millis the time in UTC milliseconds since the epoch. 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native public void set(long millis); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Format according to RFC 2445 DATETIME type. 5460df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The same as format("%Y%m%dT%H%M%S"). 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native public String format2445(); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copy the value of that to this Time object. No normalization happens. 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void set(Time that) { 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.timezone = that.timezone; 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.allDay = that.allDay; 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.second = that.second; 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.minute = that.minute; 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.hour = that.hour; 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.monthDay = that.monthDay; 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.month = that.month; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.year = that.year; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.weekDay = that.weekDay; 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.yearDay = that.yearDay; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.isDst = that.isDst; 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.gmtoff = that.gmtoff; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the fields. Sets weekDay, yearDay and gmtoff to 0, and isDst to -1. 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Call {@link #normalize(boolean)} if you need those. 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void set(int second, int minute, int hour, int monthDay, int month, int year) { 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.allDay = false; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.second = second; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.minute = minute; 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.hour = hour; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.monthDay = monthDay; 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.month = month; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.year = year; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.weekDay = 0; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.yearDay = 0; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.isDst = -1; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.gmtoff = 0; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the date from the given fields. Also sets allDay to true. 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets weekDay, yearDay and gmtoff to 0, and isDst to -1. 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Call {@link #normalize(boolean)} if you need those. 5920df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param monthDay the day of the month (in the range [1,31]) 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param month the zero-based month number (in the range [0,11]) 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param year the year 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void set(int monthDay, int month, int year) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.allDay = true; 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.second = 0; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.minute = 0; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.hour = 0; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.monthDay = monthDay; 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.month = month; 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.year = year; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.weekDay = 0; 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.yearDay = 0; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.isDst = -1; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.gmtoff = 0; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the time represented by this Time object occurs before 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the given time. 6140df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param that a given Time object to compare against 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if this time is less than the given time 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean before(Time that) { 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Time.compare(this, that) < 0; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the time represented by this Time object occurs after 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the given time. 6260df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param that a given Time object to compare against 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if this time is greater than the given time 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean after(Time that) { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Time.compare(this, that) > 0; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This array is indexed by the weekDay field (SUNDAY=0, MONDAY=1, etc.) 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and gives a number that can be added to the yearDay to give the 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * closest Thursday yearDay. 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int[] sThursdayOffset = { -3, 3, 2, 1, 0, -1, -2 }; 6400df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the week number according to ISO 8601. The current Time 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * object must already be normalized because this method uses the 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * yearDay and weekDay fields. 6450df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In IS0 8601, weeks start on Monday. 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The first week of the year (week 1) is defined by ISO 8601 as the 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * first week with four or more of its days in the starting year. 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Or equivalently, the week containing January 4. Or equivalently, 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the week with the year's first Thursday in it. 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 6530df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The week number can be calculated by counting Thursdays. Week N 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contains the Nth Thursday of the year. 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 6580df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the ISO week number. 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getWeekNumber() { 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the year day for the closest Thursday 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int closestThursday = yearDay + sThursdayOffset[weekDay]; 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Year days start at 0 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (closestThursday >= 0 && closestThursday <= 364) { 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return closestThursday / 7 + 1; 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6690df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The week crosses a year boundary. 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time temp = new Time(this); 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project temp.monthDay += sThursdayOffset[weekDay]; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project temp.normalize(true /* ignore isDst */); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return temp.yearDay / 7 + 1; 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6780df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * Return a string in the RFC 3339 format. 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If allDay is true, expresses the time as Y-M-D</p> 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Otherwise, if the timezone is UTC, expresses the time as Y-M-D-T-H-M-S UTC</p> 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Otherwise the time is expressed the time as Y-M-D-T-H-M-S +- GMT</p> 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param allDay 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return string in the RFC 3339 format. 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String format3339(boolean allDay) { 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (allDay) { 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return format(Y_M_D); 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (TIMEZONE_UTC.equals(timezone)) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return format(Y_M_D_T_H_M_S_000_Z); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String base = format(Y_M_D_T_H_M_S_000); 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String sign = (gmtoff < 0) ? "-" : "+"; 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offset = (int)Math.abs(gmtoff); 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int minutes = (offset % 3600) / 60; 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int hours = offset / 3600; 6990df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer 700315a7c0335fb54beced23b1703c10563ce02ee82Roozbeh Pournader return String.format(Locale.US, "%s%s%02d:%02d", base, sign, hours, minutes); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7030df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7050df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * Returns true if the day of the given time is the epoch on the Julian Calendar 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (January 1, 1970 on the Gregorian calendar). 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param time the time to test 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if epoch. 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isEpoch(Time time) { 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long millis = time.toMillis(true); 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getJulianDay(millis, 0) == EPOCH_JULIAN_DAY; 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7150df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the Julian day number, given the UTC milliseconds 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and the offset (in seconds) from UTC. The Julian day for a given 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * date will be the same for every timezone. For example, the Julian 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * day for July 1, 2008 is 2454649. This is the same value no matter 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * what timezone is being used. The Julian day is useful for testing 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if two events occur on the same day and for determining the relative 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * time of an event from the present ("yesterday", "3 days ago", etc.). 7240df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Use {@link #toMillis(boolean)} to get the milliseconds. 7270df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param millis the time in UTC milliseconds 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gmtoff the offset from UTC in seconds 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the Julian day 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static int getJulianDay(long millis, long gmtoff) { 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long offsetMillis = gmtoff * 1000; 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long julianDay = (millis + offsetMillis) / DateUtils.DAY_IN_MILLIS; 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (int) julianDay + EPOCH_JULIAN_DAY; 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7370df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sets the time from the given Julian day number, which must be based on 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the same timezone that is set in this Time object. The "gmtoff" field 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * need not be initialized because the given Julian day may have a different 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * GMT offset than whatever is currently stored in this Time object anyway. 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * After this method returns all the fields will be normalized and the time 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will be set to 12am at the beginning of the given Julian day. 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 7460df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The only exception to this is if 12am does not exist for that day because 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of daylight saving time. For example, Cairo, Eqypt moves time ahead one 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hour at 12am on April 25, 2008 and there are a few other places that 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * also change daylight saving time at 12am. In those cases, the time 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will be set to 1am. 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 7540df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer * 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param julianDay the Julian day in the timezone for this Time object 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the UTC milliseconds for the beginning of the Julian day 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long setJulianDay(int julianDay) { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't bother with the GMT offset since we don't know the correct 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // value for the given Julian day. Just get close and then adjust 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the day. 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long millis = (julianDay - EPOCH_JULIAN_DAY) * DateUtils.DAY_IN_MILLIS; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set(millis); 7640df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Figure out how close we are to the requested Julian day. 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We can't be off by more than a day. 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int approximateDay = getJulianDay(millis, gmtoff); 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int diff = julianDay - approximateDay; 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project monthDay += diff; 7700df10e9b4e7719777ff9a389959c5c5deeef0eaeChristian Mehlmauer 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set the time to 12am and re-normalize. 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hour = 0; 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minute = 0; 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project second = 0; 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project millis = normalize(true); 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return millis; 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 77850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 77950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 78050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Returns the week since {@link #EPOCH_JULIAN_DAY} (Jan 1, 1970) adjusted 78150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * for first day of week. This takes a julian day and the week start day and 78250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * calculates which week since {@link #EPOCH_JULIAN_DAY} that day occurs in, 78350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * starting at 0. *Do not* use this to compute the ISO week number for the 78450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * year. 78550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * 78650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param julianDay The julian day to calculate the week number for 78750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param firstDayOfWeek Which week day is the first day of the week, see 78850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * {@link #SUNDAY} 78950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @return Weeks since the epoch 79050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 79150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public static int getWeeksSinceEpochFromJulianDay(int julianDay, int firstDayOfWeek) { 79250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov int diff = THURSDAY - firstDayOfWeek; 79350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov if (diff < 0) { 79450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov diff += 7; 79550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 79650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov int refDay = EPOCH_JULIAN_DAY - diff; 79750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov return (julianDay - refDay) / 7; 79850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 79950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov 80050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov /** 80150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * Takes a number of weeks since the epoch and calculates the Julian day of 80250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * the Monday for that week. This assumes that the week containing the 80350f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * {@link #EPOCH_JULIAN_DAY} is considered week 0. It returns the Julian day 80450f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * for the Monday week weeks after the Monday of the week containing the 80550f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * epoch. 80650f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * 80750f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @param week Number of weeks since the epoch 80850f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov * @return The julian day for the Monday of the given week since the epoch 80950f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov */ 81050f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov public static int getJulianMondayFromWeeksSinceEpoch(int week) { 81150f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov return MONDAY_BEFORE_JULIAN_EPOCH + week * 7; 81250f34d14f6dd3411fdbdb6a7b8b285c2b8fdbf5cSvetoslav Ganov } 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 814