Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用GregorianCalendar循环任务一年_Java_Time_Gregorian Calendar - Fatal编程技术网

Java 使用GregorianCalendar循环任务一年

Java 使用GregorianCalendar循环任务一年,java,time,gregorian-calendar,Java,Time,Gregorian Calendar,我必须写一个程序,显示发送电子邮件的时间计划 用户正在输入开始日期,我必须显示一年的时间计划。 如何循环任务? 在本例中,邮件应每8天发送一次 if(recipient==0) { System.out.println("send mail on this day:" +calendar.getTime()); calendar.add((GregorianCalendar.DAY_OF_YEAR),8); return true;

我必须写一个程序,显示发送电子邮件的时间计划

用户正在输入开始日期,我必须显示一年的时间计划。 如何循环任务? 在本例中,邮件应每8天发送一次

    if(recipient==0) {
        System.out.println("send mail on this day:" +calendar.getTime());   
        calendar.add((GregorianCalendar.DAY_OF_YEAR),8);
        return true;    
    }
我想循环System.out.println和calendar.add任务,直到一年后

编辑:我有另一个例子,它应该每16天发送一次电子邮件,但当这一天是周六或周日时,它应该在下一个周一发送邮件

我是这样做的,但现在我得到的约会比我需要的多

if(empfaenger==1)
    {
         for (Date d=startDate; d.before(endDate); d.setTime(d.getTime() + (1000 * 60 * 60 * 24 * 8)))
         {
             if(calendar.get(calendar.DAY_OF_WEEK)==1)
            {
            calendar.add((GregorianCalendar.DAY_OF_YEAR),1);
            System.out.println("mail will be sent on this day:"+calendar.getTime());
            calendar.add((GregorianCalendar.DAY_OF_YEAR), 16);
            }
        else if(calendar.get(calendar.DAY_OF_WEEK)==7)
            {
            calendar.add((GregorianCalendar.DAY_OF_YEAR), 2);
            System.out.println("mail will be sent on this day:"+calendar.getTime());
            calendar.add((GregorianCalendar.DAY_OF_YEAR),16);
            } 
        else
        {
            System.out.println("mail will be sent on this day:"+calendar.getTime());
            calendar.add((GregorianCalendar.DAY_OF_YEAR),16);
        }
        //System.out.println(calendar.getTime;)
         }
    }
下面是一个使用java 8中的java.time api的示例,与日历或日期类相比,它更易于理解和使用:

static void sendEveryEightDays(){
    LocalDateTime timeToSendEmail= LocalDateTime.now();
    LocalDateTime afterAYear = timeToSendEmail.plusYears(1);

    while(timeToSendEmail.isBefore(afterAYear)){
        System.out.println("SendTheEmail "+timeToSendEmail.toString());
        timeToSendEmail=timeToSendEmail.plusDays(8);
    }
}
如果要考虑用户的时区,可以使用ZonedDateTime安装在LocalDateTime之外:


我想知道为什么老师们还在教旧的API日期、日历和SimpleDateFormat,因为他们有和,而且他们正在被新的API所取代。Java8于2014年发布,顺便说一句

无论如何,如果您有一个GregorianCalendar,您可以将其转换为新的java.time类,并使用它们完成其余的工作

首先,您可以使用日历创建即时:

唯一的问题是,如果您创建日历并设置日期、月份和年份,它将具有当前时间小时/分钟/秒,因此上面的时刻将具有当前UTC时间。如果没有问题,您可以将此瞬间转换为您的时区:

ZoneId zone = ZoneId.of("America/Sao_Paulo");
ZonedDateTime start = instant.atZone(zone);
我使用了美国/圣保罗,但您可以更改到对您的系统有意义的时区。API始终使用区域/城市格式,如美国/圣保罗或欧洲/柏林。 避免使用三个字母的缩写,如CST或PST,因为它们是

您可以通过调用ZoneId.GetAvailableZoneId获得可用时区的列表,并选择最适合您系统的时区。如果需要ZoneId.systemDefault,也可以使用系统的默认值,但请注意,即使在运行时,也可以在不通知的情况下更改,因此最好指定使用的时区。如果要使用UTC格式的日期,可以使用内置的常量ZoneOffset.UTC

上面的代码将创建一个ZonedDateTime,日历的日期和时间将调整到指定的时区。提醒一下,如果你做了这样的事情:

Calendar calendar = new GregorianCalendar();
calendar.set(2017, 7, 12);
该日期将相当于2017年8月12日,因为日历API中的月份从零开始,因此第7个月是8月,时间将是创建日历的当前时间

如果要指定小时,可以使用以下选项进行调整:

// change the hour/minute/second to 10:20:45
start = start.with(LocalTime.of(10, 20, 45));

// change just the hour to 10
start = start.withHour(10);

// set to start of the day
start = start.toLocalDate().atStartOfDay(zone);
使用此选项,您可以相应地更改时间和日期字段。选中和以查看所有可用选项。StartOfDay的方法更好,因为它可以根据DST的班次来处理夏令时的变化,一天可以从凌晨1点开始,而不是午夜,并且该方法可以处理所有细节

如果您不想依赖日历,也可以直接创建日期:

// creating August 12th 2017, at 10:00
start = ZonedDateTime.of(2017, 8, 12, 10, 0, 0, 0, zone);
请注意,8月份是第8个月,这是对旧API最好、最明显的改进之一

现在您已经有了开始日期,您可以循环一整年,并根据您的规则检查日期。我使用的示例是每16天发送一次电子邮件,如果是周末,则调整到下周一:

ZonedDateTime d = start;
// ends in 1 year - this method already takes care of leap years
ZonedDateTime end = start.plusYears(1);
while (end.isAfter(d)) {
    d = d.plusDays(16);
    if (d.getDayOfWeek() == DayOfWeek.SUNDAY || d.getDayOfWeek() == DayOfWeek.SATURDAY) {
        // weekend, adjust to next monday
        d = d.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
    }
    // send email
}

如果你使用的是Java,我们的老师告诉我们使用GregorianCalendar类,我就是这么做的。我能把这两种结合起来吗?我不想重写整个代码。或者有没有一种方法可以将gregoriacalendar转换为java.time?@egaal不,不要将现代的java.time类与糟糕的Calendar、gregoriacalendar、Date和其他遗留类混为一谈。java中添加了java.time类来替换那些旧类。如果你必须使用GregorianCalendar来满足你的老师,那就这样吧。但对于实际工作,只需使用java.time类。也许还可以告诉你的老师,90年代的人打电话来,他们想要回他们的约会课-一般来说答案不错,但不适合使用LocalDateTime,因为该类故意丢失时区的有价值信息。应该改为使用。使用公历会很好,但我当然可以使用java.time。我可以在Java时间也得到工作日吗?那么闰年呢?这是留给我的唯一问题,因为那时我还可以使用Java TimeyI,像,和Java.text.SimpleTextFormat这样的麻烦的旧日期时间类现在被类取代了。看。你可以通过打电话来转换,而不需要一瞬间。@BasilBourque确实,我忘了。我已经更新了我的答案,非常感谢!
// creating August 12th 2017, at 10:00
start = ZonedDateTime.of(2017, 8, 12, 10, 0, 0, 0, zone);
ZonedDateTime d = start;
// ends in 1 year - this method already takes care of leap years
ZonedDateTime end = start.plusYears(1);
while (end.isAfter(d)) {
    d = d.plusDays(16);
    if (d.getDayOfWeek() == DayOfWeek.SUNDAY || d.getDayOfWeek() == DayOfWeek.SATURDAY) {
        // weekend, adjust to next monday
        d = d.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
    }
    // send email
}