com.chiorichan.tasks.Timings.java Source code

Java tutorial

Introduction

Here is the source code for com.chiorichan.tasks.Timings.java

Source

/**
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 *
 * Copyright (c) 2017 Joel Greene <joel.greene@penoaks.com>
 * Copyright (c) 2017 Penoaks Publishing LLC <development@penoaks.com>
 *
 * All Rights Reserved.
 */
package com.chiorichan.tasks;

import java.util.Map;
import java.util.WeakHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.joda.time.Duration;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;

import com.chiorichan.utils.UtilObjects;

/**
 * Provides timing, date, and time utilities.
 */
public class Timings {
    private static final Pattern INTERVAL_PATTERN = Pattern.compile(
            "((?:\\d+)|(?:\\d+\\.\\d+))\\s*(second|minute|hour|day|week|month|year|s|m|h|d|w)",
            Pattern.CASE_INSENSITIVE);

    /*
     * Epoch Add-able Seconds
     */
    public static final int SECOND = 1;
    public static final int SECOND_15 = 15;
    public static final int SECOND_30 = 30;
    public static final int SECOND_45 = 45;

    public static final int MINUTE = 60;
    public static final int MINUTE_5 = MINUTE * 5;
    public static final int MINUTE_10 = MINUTE * 10;
    public static final int MINUTE_15 = MINUTE * 15;
    public static final int MINUTE_30 = MINUTE * 30;
    public static final int MINUTE_45 = MINUTE * 45;

    public static final int HOUR = MINUTE * 60;
    public static final int HOUR_2 = HOUR * 2;
    public static final int HOUR_3 = HOUR * 3;
    public static final int HOUR_4 = HOUR * 4;
    public static final int HOUR_6 = HOUR * 6;
    public static final int HOUR_12 = HOUR * 12;
    public static final int HOUR_18 = HOUR * 18;

    public static final int DAY = HOUR * 24;
    public static final int DAYS_3 = DAY * 3;
    public static final int DAYS_7 = DAY * 7;
    public static final int DAYS_14 = DAY * 14;
    public static final int DAYS_21 = DAY * 3;
    public static final int DAYS_28 = DAY * 28;
    public static final int DAYS_30 = DAY * 30;
    public static final int DAYS_31 = DAY * 31;

    public static final int YEAR = DAY * 365;

    /**
     * Provides reference of context to start time.<br>
     * We use a WeakHashMap to prevent a memory leak, in case {@link #finish()} is never called and/or context was reclaimed by GC.
     */
    private static final Map<Object, Long> timings = new WeakHashMap<Object, Long>();

    /**
     * The current epoch since 1970
     *
     * @return The current epoch
     */
    public static long epoch() {
        return System.currentTimeMillis() / 1000;
    }

    /**
     * Finds the total number of milliseconds it took and removes the context.
     *
     * @param context The context to reference the starting time.
     * @return The time in milliseconds it took between calling {@link #start(Object)} and this method.<br>
     * Returns {@code -1} if we have no record of ever starting.
     */
    public static long finish(Object context) {
        Long start = timings.remove(context);

        if (start == null)
            return -1;

        return System.currentTimeMillis() - start;
    }

    public static int getSecondsIn(String type) {
        type = type.toLowerCase();

        if ("second".equals(type) || "s".equals(type))
            return 1;
        else if ("minute".equals(type) || "m".equals(type))
            return 60;
        else if ("hour".equals(type) || "h".equals(type))
            return 3600;
        else if ("day".equals(type) || "d".equals(type))
            return 86400;
        else if ("week".equals(type) || "w".equals(type))
            return 604800;
        else if ("month".equals(type))
            return 2592000;
        else if ("year".equals(type))
            return 31104000;

        return 0;
    }

    /**
     * Finds the total number of milliseconds it took.
     * Be sure to still call {@link #finish(Object)} as this method is only used for checkpoints.
     *
     * @param context The context to reference the starting time.
     * @return The time in milliseconds it took between calling {@link #start(Object)} and this method.<br>
     * Returns {@code -1} if we have no record of ever starting.
     */
    public static long mark(Object context) {
        Long start = timings.get(context);

        if (start == null)
            return -1;

        return System.currentTimeMillis() - start;
    }

    /**
     * The current millis since 1970
     *
     * @return The current millis
     */
    public static long millis() {
        return System.currentTimeMillis();
    }

    /*
     * Timing Methods
     */

    public static int parseInterval(String arg) {
        if (arg.matches("^\\d+$"))
            return Integer.parseInt(arg);

        Matcher match = INTERVAL_PATTERN.matcher(arg);

        int interval = 0;

        while (match.find())
            interval += Math.round(Float.parseFloat(match.group(1)) * getSecondsIn(match.group(2)));

        return interval;
    }

    /**
     * Converts the input value into a human readable string, e.g., 0 Day(s) 3 Hour(s) 13 Minutes(s) 42 Second(s).
     *
     * @param seconds The duration in seconds
     * @return Human readable duration string
     */
    public static String readoutDuration(Number seconds) {
        Duration duration = new Duration(seconds);
        PeriodFormatter formatter = new PeriodFormatterBuilder().appendDays().appendSuffix(" Day(s) ").appendHours()
                .appendSuffix(" Hour(s) ").appendMinutes().appendSuffix(" Minute(s) ").appendSeconds()
                .appendSuffix(" Second(s)").toFormatter();
        return formatter.print(duration.toPeriod());
    }

    /**
     * See {@link #readoutDuration(Number)}
     */
    public static String readoutDuration(String seconds) {
        return readoutDuration(UtilObjects.castToInt(seconds));
    }

    /**
     * Starts the counter for the referenced context
     *
     * @param context The context to reference our start time with.
     */
    public static void start(Object context) {
        timings.put(context, System.currentTimeMillis());
    }
}