-
Notifications
You must be signed in to change notification settings - Fork 152
/
Time.java
236 lines (211 loc) · 9.54 KB
/
Time.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
package com.nyubustracker.models;
import android.content.res.Resources;
import android.support.annotation.NonNull;
import com.nyubustracker.R;
import com.nyubustracker.helpers.BusManager;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
public class Time implements Comparable<Time> {
private final TimeOfWeek timeOfWeek; // Either Weekday, Friday, Weekend.
private int hour; // In 24 hour (military) format.
private int min;
private boolean AM; // Used for parsing the input string ("8:04 PM") => 20:04, AM = true
private String route; // What route this time corresponds to.
public Time(String time, TimeOfWeek mTimeOfWeek, String mRoute) { // Input a string like "8:04 PM".
timeOfWeek = mTimeOfWeek;
route = mRoute;
AM = time.toLowerCase(Locale.ROOT).contains("am"); // Automatically accounts for AM/PM with military time.
String amOrPm = AM ? "am" : "pm";
try {
hour = Integer.parseInt(time.substring(0, time.indexOf(":")).trim());
min = Integer.parseInt(time.substring(time.indexOf(":") + 1, time.toLowerCase().indexOf(amOrPm)).trim());
} catch (Exception e) {
hour = 0;
min = 0;
AM = true;
}
if (AM && hour == 12) { // It's 12:xx AM
hour = 0;
}
if (!AM && hour != 12) { // Its x:xx PM, but not 12:xx PM.
hour += 12;
}
}
// Create a new Time given a military hour and minute.
public Time(int mHour, int mMin) {
AM = mHour < 12;
hour = mHour;
min = mMin;
timeOfWeek = getCurrentTimeOfWeek();
}
public static Time getCurrentTime(Calendar calendar) {
calendar.setTimeZone(TimeZone.getTimeZone("America/New_York"));
return new Time(calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE));
}
public static Time getCurrentTime() {
return getCurrentTime(Calendar.getInstance());
}
// compare is used to sort the list of times being checked for the "nextBusTime" in MainActivity.
// Return a negative number if Time1 is before, positive number if time2 is before, and 0 otherwise.
@Override
public int compareTo(@NonNull Time time2) {
// timeOfWeek is an enum. ordinal() returns the rank of the given TimeOfWeek.
if (this.getTimeOfWeek().ordinal() == time2.getTimeOfWeek().ordinal()) { // Times at the same time in the week.
if (this.isStrictlyBefore(time2)) { // Checks hour and minute. Returns false if they're equal or time2 is before.
return -1;
}
if (time2.isStrictlyBefore(this)) {
return 1;
}
// Same exact time (hour, minute, and timeOfWeek). So, check if we're looking at the current time.
if (this.getRoute() == null) {
return -1;
}
if (time2.getRoute() == null) {
return 1;
}
// Times are the same, but we aren't comparing the current time.
return 0;
}
return this.getTimeOfWeek().ordinal() - time2.getTimeOfWeek().ordinal();
}
private TimeOfWeek getCurrentTimeOfWeek() {
Calendar rightNow = Calendar.getInstance();
rightNow.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String dayOfWeek = rightNow.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.getDefault());
TimeOfWeek timeOfWeek = TimeOfWeek.Weekday;
if (dayOfWeek.equals("Saturday") || dayOfWeek.equals("Sunday"))
timeOfWeek = TimeOfWeek.Weekend;
else if (dayOfWeek.equals("Friday")) timeOfWeek = TimeOfWeek.Friday;
return timeOfWeek;
}
// Returns a String representation of the time of week this Time is in.
public String getTimeOfWeekAsString() {
switch (timeOfWeek) {
case Weekday:
return "Weekday";
case Friday:
return "Friday";
case Weekend:
return "Weekend";
}
//if (MainActivity.LOCAL_LOGV) Log.e("Time Debugging", "Invalid timeOfWeek");
return ""; // Should never reach here.
}
public String getRoute() {
return route;
}
// Return a nice string saying the difference between this time and the argument.
public String getTimeAsStringUntil(Time t, Resources resources) {
Time difference = this.getTimeAsTimeUntil(t);
//if (MainActivity.LOCAL_LOGV) Log.v("Time Debugging", "this: " + this.toString() + " | that: " + t.toString());
//if (MainActivity.LOCAL_LOGV) Log.v("Time Debugging", "Difference: " + difference.hour + ":" + difference.min);
if (difference != null) {
if (this.getTimeOfWeek() != t.getTimeOfWeek()) {
BusManager.getBusManager().setIsNotDuringSafeRide(false);
return resources.getString(R.string.offline);
}
if (difference.hour >= 3) {
BusManager.getBusManager().setIsNotDuringSafeRide(false);
return resources.getString(R.string.offline);
}
if (difference.hour == 0 && difference.min == 0) {
BusManager.getBusManager().setIsNotDuringSafeRide(true);
return resources.getString(R.string.less_one_minute);
}
if (difference.hour == 0 && difference.min == 1) {
BusManager.getBusManager().setIsNotDuringSafeRide(true);
return resources.getString(R.string.one_minute);
}
if (difference.hour == 0 && difference.min > 1) {
BusManager.getBusManager().setIsNotDuringSafeRide(true);
return difference.min + resources.getString(R.string.minutes);
}
if (difference.hour > 1 && difference.min == 0) {
BusManager.getBusManager().setIsNotDuringSafeRide(true);
return difference.hour + resources.getString(R.string.hours);
}
if (difference.hour == 1 && difference.min == 0) {
BusManager.getBusManager().setIsNotDuringSafeRide(true);
return resources.getString(R.string.hour);
}
if (difference.hour > 1 && difference.min == 1) {
BusManager.getBusManager().setIsNotDuringSafeRide(true);
return difference.hour + resources.getString(R.string.hours_and) + difference.min + resources.getString(R.string.one_minute);
}
if (difference.hour > 1 && difference.min > 1) {
BusManager.getBusManager().setIsNotDuringSafeRide(true);
return difference.hour + resources.getString(R.string.hours_and) + difference.min + resources.getString(R.string.minutes);
}
if (difference.hour == 1 && difference.min == 1) {
BusManager.getBusManager().setIsNotDuringSafeRide(true);
return resources.getString(R.string.hour_and_one_min);
}
if (difference.hour == 1 && difference.min > 1) {
BusManager.getBusManager().setIsNotDuringSafeRide(true);
return resources.getString(R.string.hour_and) + difference.min + resources.getString(R.string.minutes);
}
}
return "";
}
// Return a Time object who represents the difference in time between the two Times.
public Time getTimeAsTimeUntil(Time t) {
if (this.compareTo(t) <= 0) {
//if (MainActivity.LOCAL_LOGV) Log.v("Time Debugging", this + " is strictly before " + t);
int hourDifference = t.hour - this.hour;
int minDifference = t.min - this.min;
if (minDifference < 0) {
hourDifference--;
minDifference += 60;
}
return new Time(hourDifference, minDifference);
} else {
return new Time(99, 99); // This time is 'infinitely' far away.
}
}
public TimeOfWeek getTimeOfWeek() {
return timeOfWeek;
}
public boolean equals(Object t) {
if (t instanceof Time) {
Time time = (Time) t;
return (time.hour == this.hour && time.min == this.min && time.timeOfWeek == this.timeOfWeek);
}
return false;
}
public String toString() {
return getHourInNormalTime() + ":" + getMinInNormalTime() + " " + getAMorPM();
}
// Return this Time in 12-hour format.
private int getHourInNormalTime() {
if (hour == 0 && AM) return 12;
if (hour > 0 && AM) return hour;
if (hour > 12 && !AM) return hour - 12;
if (hour <= 12 && !AM) return hour;
return hour;
}
public int getHour() {
return hour;
}
public int getMinute() {
return min;
}
public boolean isAM() {
return AM;
}
// Ensure the minute string is 2 digits long.
private String getMinInNormalTime() {
if (min < 10) return "0" + min;
else return Integer.toString(min);
}
private String getAMorPM() {
return AM ? "AM" : "PM";
}
// isStrictlyBefore(t) returns false if the times are equal or this is after t.
private boolean isStrictlyBefore(Time t) {
//if (MainActivity.LOCAL_LOGV) Log.v("Time Debugging", this.toString() + " is strictly before " + t.toString() + ": " + ((this.hour < t.hour) || (this.hour == t.hour && this.min < t.min)));
return (this.hour < t.hour) || (this.hour == t.hour && this.min < t.min);
}
public enum TimeOfWeek {Weekday, Friday, Weekend}
}