1182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski/*
2908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen * Copyright (C) 2016 The Android Open Source Project
3182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski *
4182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski * you may not use this file except in compliance with the License.
6182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski * You may obtain a copy of the License at
7182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski *
8182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski *
10182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski * Unless required by applicable law or agreed to in writing, software
11182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski * See the License for the specific language governing permissions and
14182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski * limitations under the License.
15182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski */
16182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski
17182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinskipackage com.android.server.twilight;
18182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski
19908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassenimport android.text.format.DateFormat;
20908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen
210321346f38839a332e7c097a1cc80251a13b97c3Christine Franksimport java.time.Instant;
220321346f38839a332e7c097a1cc80251a13b97c3Christine Franksimport java.time.LocalDateTime;
230321346f38839a332e7c097a1cc80251a13b97c3Christine Franksimport java.time.ZoneId;
240321346f38839a332e7c097a1cc80251a13b97c3Christine Franksimport java.util.TimeZone;
25182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski
26182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski/**
27908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen * The twilight state, consisting of the sunrise and sunset times (in millis) for the current
28908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen * period.
29908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen * <p/>
30908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen * Note: This object is immutable.
31182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski */
32908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassenpublic final class TwilightState {
336384878d69d3deb4a7c314f611ee62a634f21411Justin Klaassen
34908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen    private final long mSunriseTimeMillis;
35908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen    private final long mSunsetTimeMillis;
36182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski
37e5bb03e2ea8cf0d7ab98fb6e6f8db1007d8d48d2Christine Franks    public TwilightState(long sunriseTimeMillis, long sunsetTimeMillis) {
38908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen        mSunriseTimeMillis = sunriseTimeMillis;
39908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen        mSunsetTimeMillis = sunsetTimeMillis;
40182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    }
41182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski
42182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    /**
43908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen     * Returns the time (in UTC milliseconds from epoch) of the upcoming or previous sunrise if
44908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen     * it's night or day respectively.
45182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski     */
46908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen    public long sunriseTimeMillis() {
47908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen        return mSunriseTimeMillis;
48908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen    }
49908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen
50908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen    /**
510321346f38839a332e7c097a1cc80251a13b97c3Christine Franks     * Returns a new {@link LocalDateTime} instance initialized to {@link #sunriseTimeMillis()}.
52908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen     */
530321346f38839a332e7c097a1cc80251a13b97c3Christine Franks    public LocalDateTime sunrise() {
540321346f38839a332e7c097a1cc80251a13b97c3Christine Franks        final ZoneId zoneId = TimeZone.getDefault().toZoneId();
550321346f38839a332e7c097a1cc80251a13b97c3Christine Franks        return LocalDateTime.ofInstant(Instant.ofEpochMilli(mSunriseTimeMillis), zoneId);
56182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    }
57182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski
58182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    /**
59908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen     * Returns the time (in UTC milliseconds from epoch) of the upcoming or previous sunset if
60908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen     * it's day or night respectively.
61182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski     */
62908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen    public long sunsetTimeMillis() {
63908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen        return mSunsetTimeMillis;
64908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen    }
65908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen
66908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen    /**
670321346f38839a332e7c097a1cc80251a13b97c3Christine Franks     * Returns a new {@link LocalDateTime} instance initialized to {@link #sunsetTimeMillis()}.
68908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen     */
690321346f38839a332e7c097a1cc80251a13b97c3Christine Franks    public LocalDateTime sunset() {
700321346f38839a332e7c097a1cc80251a13b97c3Christine Franks        final ZoneId zoneId = TimeZone.getDefault().toZoneId();
710321346f38839a332e7c097a1cc80251a13b97c3Christine Franks        return LocalDateTime.ofInstant(Instant.ofEpochMilli(mSunsetTimeMillis), zoneId);
72908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen    }
73908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen
74908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen    /**
75908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen     * Returns {@code true} if it is currently night time.
76908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen     */
77908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen    public boolean isNight() {
78908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen        final long now = System.currentTimeMillis();
79908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen        return now >= mSunsetTimeMillis && now < mSunriseTimeMillis;
80182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    }
81182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski
82182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    @Override
83182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    public boolean equals(Object o) {
84908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen        return o instanceof TwilightState && equals((TwilightState) o);
85182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    }
86182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski
87182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    public boolean equals(TwilightState other) {
88182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski        return other != null
89908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen                && mSunriseTimeMillis == other.mSunriseTimeMillis
90908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen                && mSunsetTimeMillis == other.mSunsetTimeMillis;
91182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    }
92182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski
93182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    @Override
94182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    public int hashCode() {
95908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen        return Long.hashCode(mSunriseTimeMillis) ^ Long.hashCode(mSunsetTimeMillis);
96182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    }
97182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski
98182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    @Override
99182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    public String toString() {
100908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen        return "TwilightState {"
101908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen                + " sunrise=" + DateFormat.format("MM-dd HH:mm", mSunriseTimeMillis)
102908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen                + " sunset="+ DateFormat.format("MM-dd HH:mm", mSunsetTimeMillis)
103908b86c796443ba4ec55c669e8a0297fc80574a6Justin Klaassen                + " }";
104182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    }
105182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski}
106