Convert org.isoron.uhabits.core.utils to Kotlin (#699)

pull/707/head
Marco Zanetti 5 years ago committed by GitHub
parent 6f2b2ab883
commit 358e1ccf42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -205,7 +205,7 @@ public class FrequencyChart extends ScrollableChart
float rowHeight = rect.height() / 8.0f; float rowHeight = rect.height() / 8.0f;
prevRect.set(rect); prevRect.set(rect);
int[] localeWeekdayList = DateUtils.getWeekdaySequence(firstWeekday); Integer[] localeWeekdayList = DateUtils.getWeekdaySequence(firstWeekday);
for (int j = 0; j < localeWeekdayList.length; j++) for (int j = 0; j < localeWeekdayList.length; j++)
{ {
rect.set(0, 0, baseSize, baseSize); rect.set(0, 0, baseSize, baseSize);

@ -32,8 +32,7 @@ import android.view.View.MeasureSpec.EXACTLY
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.common.views.ScrollableChart import org.isoron.uhabits.activities.common.views.ScrollableChart
import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.utils.DateUtils.formatHeaderDate import org.isoron.uhabits.core.utils.DateUtils
import org.isoron.uhabits.core.utils.DateUtils.getStartOfTodayCalendarWithOffset
import org.isoron.uhabits.core.utils.MidnightTimer import org.isoron.uhabits.core.utils.MidnightTimer
import org.isoron.uhabits.utils.dim import org.isoron.uhabits.utils.dim
import org.isoron.uhabits.utils.dp import org.isoron.uhabits.utils.dp
@ -115,7 +114,7 @@ class HeaderView(
} }
fun draw(canvas: Canvas) { fun draw(canvas: Canvas) {
val day = getStartOfTodayCalendarWithOffset() val day = DateUtils.getStartOfTodayCalendarWithOffset()
val width = dim(R.dimen.checkmarkWidth) val width = dim(R.dimen.checkmarkWidth)
val height = dim(R.dimen.checkmarkHeight) val height = dim(R.dimen.checkmarkHeight)
val isReversed = prefs.isCheckmarkSequenceReversed val isReversed = prefs.isCheckmarkSequenceReversed
@ -139,7 +138,7 @@ class HeaderView(
val y1 = rect.centerY() - 0.25 * em val y1 = rect.centerY() - 0.25 * em
val y2 = rect.centerY() + 1.25 * em val y2 = rect.centerY() + 1.25 * em
val lines = formatHeaderDate(day).toUpperCase().split("\n") val lines = DateUtils.formatHeaderDate(day).toUpperCase().split("\n")
canvas.drawText(lines[0], rect.centerX(), y1.toFloat(), paint) canvas.drawText(lines[0], rect.centerX(), y1.toFloat(), paint)
canvas.drawText(lines[1], rect.centerX(), y2.toFloat(), paint) canvas.drawText(lines[1], rect.centerX(), y2.toFloat(), paint)
day.add(GregorianCalendar.DAY_OF_MONTH, -1) day.add(GregorianCalendar.DAY_OF_MONTH, -1)

@ -17,31 +17,29 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.core.utils; package org.isoron.uhabits.core.utils
import androidx.annotation.*; import java.text.SimpleDateFormat
import java.util.Locale
import java.util.TimeZone
import java.text.*; class DateFormats {
import java.util.*;
public class DateFormats companion object {
{
@NonNull
public static SimpleDateFormat fromSkeleton(@NonNull String skeleton,
@NonNull Locale locale)
{
SimpleDateFormat df = new SimpleDateFormat(skeleton, locale);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
return df;
}
public static SimpleDateFormat getBackupDateFormat() @JvmStatic fun fromSkeleton(
{ skeleton: String,
return fromSkeleton("yyyy-MM-dd HHmmss", Locale.US); locale: Locale
): SimpleDateFormat {
val df = SimpleDateFormat(skeleton, locale)
df.timeZone = TimeZone.getTimeZone("UTC")
return df
} }
public static SimpleDateFormat getCSVDateFormat() @JvmStatic fun getBackupDateFormat(): SimpleDateFormat =
{ fromSkeleton("yyyy-MM-dd HHmmss", Locale.US)
return fromSkeleton("yyyy-MM-dd", Locale.US);
@JvmStatic fun getCSVDateFormat(): SimpleDateFormat =
fromSkeleton("yyyy-MM-dd", Locale.US)
} }
} }

@ -1,333 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.utils;
import androidx.annotation.*;
import org.isoron.uhabits.core.models.*;
import org.jetbrains.annotations.*;
import java.util.*;
import static java.util.Calendar.*;
public abstract class DateUtils
{
private static Long fixedLocalTime = null;
private static TimeZone fixedTimeZone = null;
private static Locale fixedLocale = null;
private static int startDayHourOffset = 0;
private static int startDayMinuteOffset = 0;
/**
* Number of milliseconds in one minute.
*/
public static final long MINUTE_LENGTH = 60 * 1000;
/**
* Number of milliseconds in one hour.
*/
public static final long HOUR_LENGTH = 60 * MINUTE_LENGTH;
/**
* Number of milliseconds in one day.
*/
public static final long DAY_LENGTH = 24 * HOUR_LENGTH;
public static long applyTimezone(long localTimestamp)
{
TimeZone tz = getTimezone();
return localTimestamp - tz.getOffset(localTimestamp - tz.getOffset(localTimestamp));
}
public static String formatHeaderDate(GregorianCalendar day)
{
Locale locale = getLocale();
String dayOfMonth = Integer.toString(day.get(DAY_OF_MONTH));
String dayOfWeek = day.getDisplayName(DAY_OF_WEEK, SHORT, locale);
return dayOfWeek + "\n" + dayOfMonth;
}
private static GregorianCalendar getCalendar(long timestamp)
{
GregorianCalendar day =
new GregorianCalendar(TimeZone.getTimeZone("GMT"), getLocale());
day.setTimeInMillis(timestamp);
return day;
}
public static long getLocalTime()
{
if (fixedLocalTime != null) return fixedLocalTime;
TimeZone tz = getTimezone();
long now = new Date().getTime();
return now + tz.getOffset(now);
}
/**
* Returns an array of strings with the names for each day of the week,
* in either SHORT or LONG format. The first entry corresponds to the
* first day of the week, according to the provided argument.
*
* @param format Either GregorianCalendar.SHORT or LONG
* @param firstWeekday An integer representing the first day of the week,
* following java.util.Calendar conventions. That is,
* Saturday corresponds to 7, and Sunday corresponds
* to 1.
*/
@NotNull
private static String[] getWeekdayNames(int format, int firstWeekday)
{
String[] days = new String[7];
Calendar calendar = new GregorianCalendar();
calendar.set(DAY_OF_WEEK, firstWeekday);
for (int i = 0; i < days.length; i++) {
days[i] = calendar.getDisplayName(DAY_OF_WEEK, format,
getLocale());
calendar.add(DAY_OF_MONTH, 1);
}
return days;
}
/**
* Returns a vector of exactly seven integers, where the first integer is
* the provided firstWeekday number, and each subsequent number is the
* previous number plus 1, wrapping back to 1 after 7. For example,
* providing 3 as firstWeekday returns {3,4,5,6,7,1,2}
*
* This function is supposed to be used to construct a sequence of weekday
* number following java.util.Calendar conventions.
*/
public static int[] getWeekdaySequence(int firstWeekday)
{
return new int[]
{
(firstWeekday - 1) % 7 + 1,
(firstWeekday) % 7 + 1,
(firstWeekday + 1) % 7 + 1,
(firstWeekday + 2) % 7 + 1,
(firstWeekday + 3) % 7 + 1,
(firstWeekday + 4) % 7 + 1,
(firstWeekday + 5) % 7 + 1,
};
}
/**
* @return An integer representing the first day of the week, according to
* the current locale. Sunday corresponds to 1, Monday to 2, and so on,
* until Saturday, which is represented by 7. This is consistent
* with java.util.Calendar constants.
*/
public static int getFirstWeekdayNumberAccordingToLocale()
{
return new GregorianCalendar().getFirstDayOfWeek();
}
/**
* @return A vector of strings with the long names for the week days,
* according to the current locale. The first entry corresponds to Saturday,
* the second entry corresponds to Monday, and so on.
*
* @param firstWeekday Either Calendar.SATURDAY, Calendar.MONDAY, or other
* weekdays defined in this class.
*/
public static String[] getLongWeekdayNames(int firstWeekday)
{
return getWeekdayNames(GregorianCalendar.LONG, firstWeekday);
}
/**
* Returns a vector of strings with the short names for the week days,
* according to the current locale. The first entry corresponds to Saturday,
* the second entry corresponds to Monday, and so on.
*
* @param firstWeekday Either Calendar.SATURDAY, Calendar.MONDAY, or other
* weekdays defined in this class.
*/
public static String[] getShortWeekdayNames(int firstWeekday)
{
return getWeekdayNames(GregorianCalendar.SHORT, firstWeekday);
}
@NonNull
public static Timestamp getToday()
{
return new Timestamp(getStartOfToday());
}
@NonNull
public static Timestamp getTodayWithOffset()
{
return new Timestamp(getStartOfTodayWithOffset());
}
public static long getStartOfDay(long timestamp)
{
return (timestamp / DAY_LENGTH) * DAY_LENGTH;
}
public static long getStartOfDayWithOffset(long timestamp)
{
long offset = startDayHourOffset * HOUR_LENGTH + startDayMinuteOffset * MINUTE_LENGTH;
return getStartOfDay(timestamp - offset);
}
public static long getStartOfToday()
{
return getStartOfDay(getLocalTime());
}
public static long getStartOfTomorrowWithOffset()
{
return getUpcomingTimeInMillis(startDayHourOffset, startDayMinuteOffset);
}
public static long getStartOfTodayWithOffset()
{
return getStartOfDayWithOffset(getLocalTime());
}
public static long millisecondsUntilTomorrowWithOffset()
{
return getStartOfTomorrowWithOffset() - getLocalTime();
}
public static GregorianCalendar getStartOfTodayCalendar()
{
return getCalendar(getStartOfToday());
}
public static GregorianCalendar getStartOfTodayCalendarWithOffset()
{
return getCalendar(getStartOfTodayWithOffset());
}
private static TimeZone getTimezone()
{
if(fixedTimeZone != null) return fixedTimeZone;
return TimeZone.getDefault();
}
public static void setFixedTimeZone(TimeZone tz)
{
fixedTimeZone = tz;
}
public static long removeTimezone(long timestamp)
{
TimeZone tz = getTimezone();
return timestamp + tz.getOffset(timestamp);
}
public static void setFixedLocalTime(Long timestamp)
{
fixedLocalTime = timestamp;
}
public static void setFixedLocale(Locale locale)
{
fixedLocale = locale;
}
public static void setStartDayOffset(int hourOffset, int minuteOffset)
{
startDayHourOffset = hourOffset;
startDayMinuteOffset = minuteOffset;
}
private static Locale getLocale()
{
if(fixedLocale != null) return fixedLocale;
return Locale.getDefault();
}
public static Timestamp truncate(TruncateField field,
Timestamp timestamp,
int firstWeekday)
{
return new Timestamp(truncate(field, timestamp.getUnixTime(), firstWeekday));
}
public static Long truncate(TruncateField field,
long timestamp,
int firstWeekday)
{
GregorianCalendar cal = DateUtils.getCalendar(timestamp);
switch (field)
{
case DAY:
return cal.getTimeInMillis();
case MONTH:
cal.set(DAY_OF_MONTH, 1);
return cal.getTimeInMillis();
case WEEK_NUMBER:
int weekday = cal.get(DAY_OF_WEEK);
int delta = weekday - firstWeekday;
if (delta < 0) delta += 7;
cal.add(Calendar.DAY_OF_YEAR, -delta);
return cal.getTimeInMillis();
case QUARTER:
int quarter = cal.get(Calendar.MONTH) / 3;
cal.set(DAY_OF_MONTH, 1);
cal.set(Calendar.MONTH, quarter * 3);
return cal.getTimeInMillis();
case YEAR:
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(DAY_OF_MONTH, 1);
return cal.getTimeInMillis();
default:
throw new IllegalArgumentException();
}
}
public static long getUpcomingTimeInMillis(int hour, int minute)
{
Calendar calendar = DateUtils.getStartOfTodayCalendar();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
long time = calendar.getTimeInMillis();
if (DateUtils.getLocalTime() > time)
time += DateUtils.DAY_LENGTH;
return applyTimezone(time);
}
public enum TruncateField
{
DAY, MONTH, WEEK_NUMBER, YEAR, QUARTER
}
}

@ -0,0 +1,331 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.utils
import org.isoron.uhabits.core.models.Timestamp
import java.util.Calendar
import java.util.Calendar.DAY_OF_MONTH
import java.util.Calendar.DAY_OF_WEEK
import java.util.Calendar.SHORT
import java.util.Date
import java.util.GregorianCalendar
import java.util.Locale
import java.util.TimeZone
abstract class DateUtils {
companion object {
private var fixedLocalTime: Long? = null
private var fixedTimeZone: TimeZone? = null
private var fixedLocale: Locale? = null
private var startDayHourOffset: Int = 0
private var startDayMinuteOffset: Int = 0
/**
* Number of milliseconds in one minute.
*/
const val MINUTE_LENGTH: Long = 60 * 1000
/**
* Number of milliseconds in one hour.
*/
const val HOUR_LENGTH: Long = 60 * MINUTE_LENGTH
/**
* Number of milliseconds in one day.
*/
const val DAY_LENGTH: Long = 24 * HOUR_LENGTH
@JvmStatic
fun applyTimezone(localTimestamp: Long): Long {
val tz: TimeZone = getTimeZone()
return localTimestamp - tz.getOffset(localTimestamp - tz.getOffset(localTimestamp))
}
@JvmStatic
fun formatHeaderDate(day: GregorianCalendar): String {
val locale = getLocale()
val dayOfMonth: String = day.get(DAY_OF_MONTH).toString()
val dayOfWeek = day.getDisplayName(DAY_OF_WEEK, SHORT, locale)
return dayOfWeek + "\n" + dayOfMonth
}
private fun getCalendar(timestamp: Long): GregorianCalendar {
val day = GregorianCalendar(TimeZone.getTimeZone("GMT"), getLocale())
day.timeInMillis = timestamp
return day
}
@JvmStatic
fun getLocalTime(): Long {
if (fixedLocalTime != null) return fixedLocalTime as Long
val tz = getTimeZone()
val now = Date().getTime()
return now + tz.getOffset(now)
}
/**
* Returns an array of strings with the names for each day of the week,
* in either SHORT or LONG format. The first entry corresponds to the
* first day of the week, according to the provided argument.
*
* @param format Either GregorianCalendar.SHORT or LONG
* @param firstWeekDay An integer representing the first day of the week,
* following java.util.Calendar conventions. That is,
* Saturday corresponds to 7, and Sunday corresponds
* to 1.
*/
private fun getWeekdayNames(
format: Int,
firstWeekDay: Int
): Array<String> {
val calendar = GregorianCalendar()
calendar.set(DAY_OF_WEEK, firstWeekDay)
val daysNullable = ArrayList<String>()
for (i in 1..7) {
daysNullable.add(
calendar.getDisplayName(
DAY_OF_WEEK,
format,
getLocale()
)
)
calendar.add(DAY_OF_MONTH, 1)
}
return daysNullable.toTypedArray()
}
/**
* Returns a vector of exactly seven integers, where the first integer is
* the provided firstWeekday number, and each subsequent number is the
* previous number plus 1, wrapping back to 1 after 7. For example,
* providing 3 as firstWeekday returns {3,4,5,6,7,1,2}
*
* This function is supposed to be used to construct a sequence of weekday
* number following java.util.Calendar conventions.
*/
@JvmStatic
fun getWeekdaySequence(firstWeekday: Int): Array<Int> {
return arrayOf(
(firstWeekday - 1) % 7 + 1,
(firstWeekday) % 7 + 1,
(firstWeekday + 1) % 7 + 1,
(firstWeekday + 2) % 7 + 1,
(firstWeekday + 3) % 7 + 1,
(firstWeekday + 4) % 7 + 1,
(firstWeekday + 5) % 7 + 1,
)
}
/**
* @return An integer representing the first day of the week, according to
* the current locale. Sunday corresponds to 1, Monday to 2, and so on,
* until Saturday, which is represented by 7. This is consistent
* with java.util.Calendar constants.
*/
@JvmStatic
fun getFirstWeekdayNumberAccordingToLocale(): Int {
return GregorianCalendar().firstDayOfWeek
}
/**
* @return A vector of strings with the long names for the week days,
* according to the current locale. The first entry corresponds to Saturday,
* the second entry corresponds to Monday, and so on.
*
* @param firstWeekday Either Calendar.SATURDAY, Calendar.MONDAY, or other
* weekdays defined in this class.
*/
@JvmStatic
fun getLongWeekdayNames(firstWeekday: Int): Array<String> {
return getWeekdayNames(GregorianCalendar.LONG, firstWeekday)
}
/**
* Returns a vector of strings with the short names for the week days,
* according to the current locale. The first entry corresponds to Saturday,
* the second entry corresponds to Monday, and so on.
*
* @param firstWeekday Either Calendar.SATURDAY, Calendar.MONDAY, or other
* weekdays defined in this class.
*/
@JvmStatic
fun getShortWeekdayNames(firstWeekday: Int): Array<String> {
return getWeekdayNames(GregorianCalendar.SHORT, firstWeekday)
}
@JvmStatic
fun getToday(): Timestamp = Timestamp(getStartOfToday())
@JvmStatic
fun getTodayWithOffset(): Timestamp = Timestamp(getStartOfTodayWithOffset())
@JvmStatic
fun getStartOfDay(timestamp: Long): Long = (timestamp / DAY_LENGTH) * DAY_LENGTH
@JvmStatic
fun getStartOfDayWithOffset(timestamp: Long): Long {
val offset = startDayHourOffset * HOUR_LENGTH + startDayMinuteOffset * MINUTE_LENGTH
return getStartOfDay(timestamp - offset)
}
@JvmStatic
fun getStartOfToday(): Long = getStartOfDay(getLocalTime())
@JvmStatic
fun getStartOfTomorrowWithOffset(): Long = getUpcomingTimeInMillis(
startDayHourOffset,
startDayMinuteOffset
)
@JvmStatic
fun getStartOfTodayWithOffset(): Long = getStartOfDayWithOffset(getLocalTime())
@JvmStatic
fun millisecondsUntilTomorrowWithOffset(): Long = getStartOfTomorrowWithOffset() - getLocalTime()
@JvmStatic
fun getStartOfTodayCalendar(): GregorianCalendar = getCalendar(getStartOfToday())
@JvmStatic
fun getStartOfTodayCalendarWithOffset(): GregorianCalendar = getCalendar(getStartOfTodayWithOffset())
@JvmStatic
fun getTimeZone(): TimeZone {
return fixedTimeZone ?: TimeZone.getDefault()
}
@JvmStatic
fun getTimezone(): TimeZone {
return fixedTimeZone ?: TimeZone.getDefault()
}
@JvmStatic
fun removeTimezone(timestamp: Long): Long {
val tz = getTimeZone()
return timestamp + tz.getOffset(timestamp)
}
@JvmStatic
fun setStartDayOffset(hourOffset: Int, minuteOffset: Int) {
startDayHourOffset = hourOffset
startDayMinuteOffset = minuteOffset
}
@JvmStatic
fun getLocale(): Locale {
return fixedLocale ?: Locale.getDefault()
}
@JvmStatic
fun truncate(
field: TruncateField,
timestamp: Timestamp,
firstWeekday: Int
): Timestamp {
return Timestamp(
truncate(
field,
timestamp.unixTime,
firstWeekday
)
)
}
@JvmStatic
fun truncate(
field: TruncateField,
timestamp: Long,
firstWeekday: Int
): Long {
val cal = getCalendar(timestamp)
return when (field) {
TruncateField.DAY -> { cal.timeInMillis }
TruncateField.MONTH -> {
cal.set(DAY_OF_MONTH, 1)
cal.timeInMillis
}
TruncateField.WEEK_NUMBER -> {
val weekDay = cal.get(DAY_OF_WEEK)
var delta = weekDay - firstWeekday
if (delta < 0) { delta += 7 }
cal.add(Calendar.DAY_OF_YEAR, -delta)
cal.timeInMillis
}
TruncateField.QUARTER -> {
val quarter = cal.get(Calendar.MONTH) / 3
cal.set(DAY_OF_MONTH, 1)
cal.set(Calendar.MONTH, quarter * 3)
cal.timeInMillis
}
TruncateField.YEAR -> {
cal.set(Calendar.MONTH, Calendar.JANUARY)
cal.set(DAY_OF_MONTH, 1)
cal.timeInMillis
}
}
}
@JvmStatic
fun getUpcomingTimeInMillis(
hour: Int,
minute: Int
): Long {
val calendar = getStartOfTodayCalendar()
calendar.set(Calendar.HOUR_OF_DAY, hour)
calendar.set(Calendar.MINUTE, minute)
calendar.set(Calendar.SECOND, 0)
var time = calendar.timeInMillis
if (getLocalTime() > time) {
time += DAY_LENGTH
}
return applyTimezone(time)
}
@JvmStatic
fun setFixedLocalTime(newFixedLocalTime: Long?) {
this.fixedLocalTime = newFixedLocalTime
}
@JvmStatic
fun setFixedTimeZone(newTimeZone: TimeZone?) {
this.fixedTimeZone = newTimeZone
}
@JvmStatic
fun setFixedLocale(newLocale: Locale?) {
this.fixedLocale = newLocale
}
}
enum class TruncateField {
DAY, MONTH, WEEK_NUMBER, YEAR, QUARTER
}
}

@ -1,77 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.utils;
import org.isoron.uhabits.core.*;
import java.util.*;
import java.util.concurrent.*;
import javax.inject.*;
/**
* A class that emits events when a new day starts.
*/
@AppScope
public class MidnightTimer
{
private final List<MidnightListener> listeners;
private ScheduledExecutorService executor;
@Inject
public MidnightTimer()
{
this.listeners = new LinkedList<>();
}
public synchronized void addListener(MidnightListener listener)
{
this.listeners.add(listener);
}
public synchronized void onPause()
{
executor.shutdownNow();
}
public synchronized void onResume()
{
executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(() -> notifyListeners(),
DateUtils.millisecondsUntilTomorrowWithOffset() + 1000,
DateUtils.DAY_LENGTH, TimeUnit.MILLISECONDS);
}
public synchronized void removeListener(MidnightListener listener)
{
this.listeners.remove(listener);
}
private synchronized void notifyListeners()
{
for (MidnightListener l : listeners) l.atMidnight();
}
public interface MidnightListener
{
void atMidnight();
}
}

@ -0,0 +1,63 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.utils
import org.isoron.uhabits.core.AppScope
import java.util.LinkedList
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit
import javax.inject.Inject
/**
* A class that emits events when a new day starts.
*/
@AppScope
open class MidnightTimer @Inject constructor() {
private val listeners: MutableList<MidnightListener> = LinkedList()
private lateinit var executor: ScheduledExecutorService
@Synchronized fun addListener(listener: MidnightListener) {
this.listeners.add(listener)
}
@Synchronized fun onPause() = executor.shutdownNow()
@Synchronized fun onResume() {
executor = Executors.newSingleThreadScheduledExecutor()
executor.scheduleAtFixedRate(
{ notifyListeners() },
DateUtils.millisecondsUntilTomorrowWithOffset() + 1000,
DateUtils.DAY_LENGTH,
TimeUnit.MILLISECONDS
)
}
@Synchronized fun removeListener(listener: MidnightListener) = this.listeners.remove(listener)
@Synchronized private fun notifyListeners() {
for (l in listeners) {
l.atMidnight()
}
}
interface MidnightListener {
fun atMidnight()
}
}

@ -1,67 +0,0 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.utils;
import org.apache.commons.lang3.builder.*;
import java.math.*;
import java.util.*;
public class StringUtils
{
private static StandardToStringStyle toStringStyle = null;
public static String getRandomId()
{
return new BigInteger(260, new Random()).toString(32).substring(0, 32);
}
public static ToStringStyle defaultToStringStyle()
{
if (toStringStyle == null)
{
toStringStyle = new StandardToStringStyle();
toStringStyle.setFieldSeparator(", ");
toStringStyle.setUseClassName(false);
toStringStyle.setUseIdentityHashCode(false);
toStringStyle.setContentStart("{");
toStringStyle.setContentEnd("}");
toStringStyle.setFieldNameValueSeparator(": ");
toStringStyle.setArrayStart("[");
toStringStyle.setArrayEnd("]");
}
return toStringStyle;
}
public static String joinLongs(long values[])
{
return org.apache.commons.lang3.StringUtils.join(values, ',');
}
public static long[] splitLongs(String str)
{
String parts[] = org.apache.commons.lang3.StringUtils.split(str, ',');
long numbers[] = new long[parts.length];
for (int i = 0; i < parts.length; i++) numbers[i] = Long.valueOf(parts[i]);
return numbers;
}
}

@ -0,0 +1,69 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.core.utils
import org.apache.commons.lang3.builder.StandardToStringStyle
import org.apache.commons.lang3.builder.ToStringStyle
import java.math.BigInteger
import java.util.Random
class StringUtils {
companion object {
private lateinit var toStringStyle: StandardToStringStyle
@JvmStatic
fun getRandomId(): String {
return BigInteger(260, Random()).toString(32).subSequence(0, 32).toString()
}
@JvmStatic
fun defaultToStringStyle(): ToStringStyle {
toStringStyle = StandardToStringStyle()
toStringStyle.apply {
fieldSeparator = ", "
isUseClassName = false
isUseIdentityHashCode = false
contentStart = "{"
contentEnd = "}"
fieldNameValueSeparator = ": "
arrayStart = "["
arrayEnd = "]"
}
return toStringStyle
}
@JvmStatic
fun joinLongs(values: LongArray): String {
return org.apache.commons.lang3.StringUtils.join(values, ',')
}
@JvmStatic
fun splitLongs(str: String): LongArray {
val parts: Array<String> = org.apache.commons.lang3.StringUtils.split(str, ',')
val numbers = LongArray(parts.size) {
i ->
parts[i].toLong()
}
return numbers
}
}
}
Loading…
Cancel
Save