All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.espertech.esper.epl.datetime.calop.CalendarOpPlusMinus Maven / Gradle / Ivy

There is a newer version: 7.1.0
Show newest version
/*
 ***************************************************************************************
 *  Copyright (C) 2006 EsperTech, Inc. All rights reserved.                            *
 *  http://www.espertech.com/esper                                                     *
 *  http://www.espertech.com                                                           *
 *  ---------------------------------------------------------------------------------- *
 *  The software in this package is published under the terms of the GPL license       *
 *  a copy of which has been included with this distribution in the license.txt file.  *
 ***************************************************************************************
 */
package com.espertech.esper.epl.datetime.calop;

import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.util.TimePeriod;
import com.espertech.esper.epl.expression.core.ExprEvaluator;
import com.espertech.esper.epl.expression.core.ExprEvaluatorContext;

import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;

public class CalendarOpPlusMinus implements CalendarOp {

    private final ExprEvaluator param;
    private final int factor;

    public CalendarOpPlusMinus(ExprEvaluator param, int factor) {
        this.param = param;
        this.factor = factor;
    }

    public void evaluate(Calendar cal, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
        Object value = param.evaluate(eventsPerStream, isNewData, context);
        if (value instanceof Number) {
            action(cal, factor, ((Number) value).longValue());
        } else {
            action(cal, factor, (TimePeriod) value);
        }
    }

    public LocalDateTime evaluate(LocalDateTime ldt, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
        Object value = param.evaluate(eventsPerStream, isNewData, context);
        if (value instanceof Number) {
            return action(ldt, factor, ((Number) value).longValue());
        } else {
            return action(ldt, factor, (TimePeriod) value);
        }
    }

    public ZonedDateTime evaluate(ZonedDateTime zdt, EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
        Object value = param.evaluate(eventsPerStream, isNewData, context);
        if (value instanceof Number) {
            return action(zdt, factor, ((Number) value).longValue());
        } else {
            return action(zdt, factor, (TimePeriod) value);
        }
    }

    protected static void action(Calendar cal, int factor, Long duration) {
        if (duration == null) {
            return;
        }
        if (duration < Integer.MAX_VALUE) {
            cal.add(Calendar.MILLISECOND, (int) (factor * duration));
            return;
        }

        int days = (int) (duration / (1000L * 60 * 60 * 24));
        int msec = (int) (duration - days * (1000L * 60 * 60 * 24));
        cal.add(Calendar.MILLISECOND, factor * msec);
        cal.add(Calendar.DATE, factor * days);
    }

    protected static LocalDateTime action(LocalDateTime ldt, int factor, Long duration) {
        if (duration == null) {
            return ldt;
        }
        if (duration < Integer.MAX_VALUE) {
            return ldt.plus(factor * duration, ChronoUnit.MILLIS);
        }

        int days = (int) (duration / (1000L * 60 * 60 * 24));
        int msec = (int) (duration - days * (1000L * 60 * 60 * 24));
        ldt = ldt.plus(factor * msec, ChronoUnit.MILLIS);
        return ldt.plus(factor * days, ChronoUnit.DAYS);
    }

    protected static ZonedDateTime action(ZonedDateTime ldt, int factor, Long duration) {
        if (duration == null) {
            return ldt;
        }
        if (duration < Integer.MAX_VALUE) {
            return ldt.plus(factor * duration, ChronoUnit.MILLIS);
        }

        int days = (int) (duration / (1000L * 60 * 60 * 24));
        int msec = (int) (duration - days * (1000L * 60 * 60 * 24));
        ldt = ldt.plus(factor * msec, ChronoUnit.MILLIS);
        return ldt.plus(factor * days, ChronoUnit.DAYS);
    }

    public static void actionSafeOverflow(Calendar cal, int factor, TimePeriod tp) {
        if (Math.abs(factor) == 1) {
            action(cal, factor, tp);
            return;
        }
        Integer max = tp.largestAbsoluteValue();
        if (max == null || max == 0) {
            return;
        }
        actionHandleOverflow(cal, factor, tp, max);
    }

    public static void action(Calendar cal, int factor, TimePeriod tp) {
        if (tp == null) {
            return;
        }
        if (tp.getYears() != null) {
            cal.add(Calendar.YEAR, factor * tp.getYears());
        }
        if (tp.getMonths() != null) {
            cal.add(Calendar.MONTH, factor * tp.getMonths());
        }
        if (tp.getWeeks() != null) {
            cal.add(Calendar.WEEK_OF_YEAR, factor * tp.getWeeks());
        }
        if (tp.getDays() != null) {
            cal.add(Calendar.DATE, factor * tp.getDays());
        }
        if (tp.getHours() != null) {
            cal.add(Calendar.HOUR_OF_DAY, factor * tp.getHours());
        }
        if (tp.getMinutes() != null) {
            cal.add(Calendar.MINUTE, factor * tp.getMinutes());
        }
        if (tp.getSeconds() != null) {
            cal.add(Calendar.SECOND, factor * tp.getSeconds());
        }
        if (tp.getMilliseconds() != null) {
            cal.add(Calendar.MILLISECOND, factor * tp.getMilliseconds());
        }
    }

    private static LocalDateTime action(LocalDateTime ldt, int factor, TimePeriod tp) {
        if (tp == null) {
            return ldt;
        }
        if (tp.getYears() != null) {
            ldt = ldt.plus(factor * tp.getYears(), ChronoUnit.YEARS);
        }
        if (tp.getMonths() != null) {
            ldt = ldt.plus(factor * tp.getMonths(), ChronoUnit.MONTHS);
        }
        if (tp.getWeeks() != null) {
            ldt = ldt.plus(factor * tp.getWeeks(), ChronoUnit.WEEKS);
        }
        if (tp.getDays() != null) {
            ldt = ldt.plus(factor * tp.getDays(), ChronoUnit.DAYS);
        }
        if (tp.getHours() != null) {
            ldt = ldt.plus(factor * tp.getHours(), ChronoUnit.HOURS);
        }
        if (tp.getMinutes() != null) {
            ldt = ldt.plus(factor * tp.getMinutes(), ChronoUnit.MINUTES);
        }
        if (tp.getSeconds() != null) {
            ldt = ldt.plus(factor * tp.getSeconds(), ChronoUnit.SECONDS);
        }
        if (tp.getMilliseconds() != null) {
            ldt = ldt.plus(factor * tp.getMilliseconds(), ChronoUnit.MILLIS);
        }
        return ldt;
    }

    private static ZonedDateTime action(ZonedDateTime zdt, int factor, TimePeriod tp) {
        if (tp == null) {
            return zdt;
        }
        if (tp.getYears() != null) {
            zdt = zdt.plus(factor * tp.getYears(), ChronoUnit.YEARS);
        }
        if (tp.getMonths() != null) {
            zdt = zdt.plus(factor * tp.getMonths(), ChronoUnit.MONTHS);
        }
        if (tp.getWeeks() != null) {
            zdt = zdt.plus(factor * tp.getWeeks(), ChronoUnit.WEEKS);
        }
        if (tp.getDays() != null) {
            zdt = zdt.plus(factor * tp.getDays(), ChronoUnit.DAYS);
        }
        if (tp.getHours() != null) {
            zdt = zdt.plus(factor * tp.getHours(), ChronoUnit.HOURS);
        }
        if (tp.getMinutes() != null) {
            zdt = zdt.plus(factor * tp.getMinutes(), ChronoUnit.MINUTES);
        }
        if (tp.getSeconds() != null) {
            zdt = zdt.plus(factor * tp.getSeconds(), ChronoUnit.SECONDS);
        }
        if (tp.getMilliseconds() != null) {
            zdt = zdt.plus(factor * tp.getMilliseconds(), ChronoUnit.MILLIS);
        }
        return zdt;
    }

    private static void actionHandleOverflow(Calendar cal, int factor, TimePeriod tp, int max) {
        if (max != 0 && factor > Integer.MAX_VALUE / max) {
            // overflow
            int first = factor / 2;
            int second = (factor - first * 2) + first;
            actionHandleOverflow(cal, first, tp, max);
            actionHandleOverflow(cal, second, tp, max);
        } else {
            // no overflow
            action(cal, factor, tp);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy