如何用Java对象最好地表示营业时间?

11

我需要表示营业时间,并且需要一个方法来判断某一天和时间是否在营业时间内返回真/假。 是否有任何包含此功能的软件包?

编辑:基本上我需要构建一个包含从数据库或文件中获取的数据的对象,然后对该对象执行基本检查,例如它是否在某一时刻关闭。

问题是,有些企业在00:00之后仍然有营业时间,因此与下一天重叠。 在这种情况下,我发现该对象应该能够支持每天多个时间段,以及午休时间。


1
任何软件包都无法满足您所陈述的要求,因为它太过模糊。实际上,营业时间是由一组“营业规则”确定的。您对哪些营业规则感兴趣? - Raedwald
5个回答

7

您可以使用 Calendar 创建一个类,然后查看现在是否是工作日和工作小时。

class BusinessHour{

public void isOpenNow(){
  Calendar calNow = Calendar.getInstance();
    //check the rules for example , if day is MOn-FRi and time is 9-18.
  }
}

我认为不会有现成的解决方案,因为每个企业都有自己的规格要求。您可以使其可配置化,以适用于所有企业,并将conf参数提供给类外部,以获得更好的设计。


5
在Java 8中,您可以将其表示为一组openingTimes对象:
这个集合:
 Set<OpeningTimes> openingTimes = new HashSet<>();

营业时间

import java.time.DayOfWeek;
import java.time.LocalTime;

public class OpeningTimes {
    private DayOfWeek dayOfWeek;
    private LocalTime from;
    private LocalTime to;

    public DayOfWeek getDayOfWeek() {
        return dayOfWeek;
    }

    public void setDayOfWeek(DayOfWeek dayOfWeek) {
        this.dayOfWeek = dayOfWeek;
    }

    public LocalTime getFrom() {
        return from;
    }

    public void setFrom(LocalTime from) {
        this.from = from;
    }

    public LocalTime getTo() {
        return to;
    }

    public void setTo(LocalTime to) {
        this.to = to;
    }
}

这并不考虑主题完全关闭的日子。 - Aron Hoogeveen

5

我使用以下对象将“OpeningHours”存储在HashSet中。下面的示例可以很容易地简化,使用从午夜开始的秒数代替“800”或“1600”作为小时数,但我喜欢这种方式。

public class OpeningHours {
  public enum DAY {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
  }

public OpeningHours(DAY day, Integer from, Integer to) {
    this.day = day;
    this.from = from; // format time using 800 for 8:00am or 2300 for 23:00
    this.to = to;
}

@Override
public String toString() {
    return "OpeningHours [day=" + day + ", from=" + from + ", to=" + to + ", isAllDay=" + isAllDay + "]";
}

public OpeningHours() {

}

public DAY day;
public Integer from;
public Integer to;
public boolean isAllDay = false;

public void isOpenx(DateTime start) {

}

public boolean isOpen(DateTime start) {

    if (day.ordinal() != start.getDayOfWeek() - 1) {
        return false;
    }

    if (isAllDay)
        return true;

    String f = String.format("%04d", from);
    String t = String.format("%04d", to);

    Integer fh = Integer.valueOf(f.substring(0, 2));
    Integer fm = Integer.valueOf(f.substring(2));

    Integer th = Integer.valueOf(t.substring(0, 2));
    Integer tm = Integer.valueOf(t.substring(2));

    DateTime intStart = start.withHourOfDay(fh).withMinuteOfHour(fm);
    DateTime intEnd = start.withHourOfDay(th).withMinuteOfHour(tm);

    if (intStart.equals(start) || intEnd.equals(start)) {
        return true;
    }
    if (intStart.isBefore(start) && intEnd.isAfter(start)) {
        return true;
    }

    return false;

}
}

HashSet<OpeningHours> hours = new HashSet<OpeningHours>();
hours.add(new OpeningHours(OpeningHours.DAY.MONDAY, 800, 1200));
hours.add(new OpeningHours(OpeningHours.DAY.MONDAY, 1230, 1600));


DateTime dateToCheck = new DateTime(2012, 9, 4, 8, 00, 0, 0);

for (OpeningHours item : hours) {
  boolean isOpen = item.isOpen(dateToCheck );
  if (isOpen){
    System.out.println("Is Open!");
  }
}

2

很可能没有一个已经实现您确切业务逻辑的软件包。

例如,您是否需要在某些特定日期覆盖标准开放日,例如特殊活动的关闭?公共假期呢?您是否会为此而开放?

我的简单建议解决方案是:

  1. 创建一个数据库表,字段为(日期,开放时间,关闭时间)
  2. 创建一个函数,以日期和时间作为参数,并查找数据库表以确定给定日期的开放/关闭时间是否在其中
  3. 提供一种简单的方法,让业务用户在预先填充标准时间后更新开放/关闭时间

0
以下类还考虑了指定日期某物(例如建筑物)完全不开放的情况。
import org.jetbrains.annotations.NotNull;

import java.time.LocalTime;
import java.util.Objects;

/**
 * {@code OpeningHours} represents the opening hours of a single day of a "thing"
 * (e.g. a building). The opening- and closing hour are independent of timezones.
 */
public class OpeningHours {
    private boolean opensToday;
    private LocalTime openingHour;
    private LocalTime closingHour;

    /**
     * A reusable {@code OpeningHours} that is always closed.
     */
    private static OpeningHours closedInstance = new OpeningHours();

    /**
     * Constructs a new {@code OpeningHours} for a thing that does not open at this specific day.
     */
    public OpeningHours() {
        opensToday = false;
    }

    /**
     * Constructs a new {@code OpeningHours} for a thing that does open today.
     *
     * @param openingHour the opening hour of the thing, inclusive. Must be strictly less than the closingHour
     * @param closingHour the closing hour of the thing, exclusive. Must be strictly more than the openingHour
     */
    public OpeningHours(@NotNull LocalTime openingHour, @NotNull LocalTime closingHour) {
        Objects.requireNonNull(openingHour);
        Objects.requireNonNull(closingHour);

        if (openingHour.compareTo(closingHour) >= 0)
            throw new IllegalArgumentException("the openingHour must be strictly less than the closingHour");

        this.opensToday = true;
        this.openingHour = openingHour;
        this.closingHour = closingHour;
    }

    /**
     * Returns whether the thing this {@code OpeningHours} belongs to will open today.
     *
     * @return the value of {@link #opensToday}
     */
    public boolean opensToday() {
        return opensToday;
    }

    /**
     * Returns whether the provided {@code time} is within the opening hours. More specifically this method returns
     * {@code true} when {@code time} is equal to or greater than {@code this#getOpeningHour()} and strictly less
     * than {@code this.getClosingHour()}.
     *
     * @param time the time at wh
     * @return {@code true} if {@code time} is greater than or equal to {@link #openingHour} and strictly less than
     *         {@link #closingHour}.
     */
    public boolean isOpen(LocalTime time) {
        if (!opensToday)
            return false;
        return (openingHour.compareTo(time) <= 0) && (closingHour.compareTo(time) > 0) ;
    }

    /**
     * Returns whether the current time is within the opening hours.
     * 
     * @see #isOpen(LocalTime)
     */
    public boolean isOpen() {
        return this.isOpen(LocalTime.now());
    }


    /**
     * @return an {@code OpeningHours} for a thing that is permanently closed on this day.
     */
    public OpeningHours getClosedInstance() {
        return closedInstance;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        OpeningHours that = (OpeningHours) o;

        if (opensToday != that.opensToday) return false;
        if (!Objects.equals(openingHour, that.openingHour)) return false;
        return Objects.equals(closingHour, that.closingHour);
    }

    @Override
    public int hashCode() {
        int result = (opensToday ? 1 : 0);
        result = 31 * result + (openingHour != null ? openingHour.hashCode() : 0);
        result = 31 * result + (closingHour != null ? closingHour.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "OpeningHours{" +
                "opensToday=" + opensToday +
                ", openingHour=" + openingHour +
                ", closingHour=" + closingHour +
                '}';
    }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接