列表中的日历类型元素
Posted
技术标签:
【中文标题】列表中的日历类型元素【英文标题】:calendar type elements in a list 【发布时间】:2018-03-12 02:47:28 【问题描述】:我必须创建一个程序,它打印出日期列表(年、月、日),直到用户选择的日期(end_date
后来转换为end_cal
)。
例如,如果今天是2017-09-30 Saturday
,用户输入日期2017-10-30
,程序必须打印出这些日期:
2017-09-30、2017-10-07、2017-10-14、2017-10-21、2017-10-28。
问题:
-
将日历类型元素添加到列表中
打印列表。
在打印添加到列表期间格式化日期
当我尝试打印它时,输出只是一堆相同日期的重复。
public class Weekdays
static Scanner input = new Scanner(System.in);
static Calendar temp_cal = Calendar.getInstance(); //temporary calendar object. it's value is being chaged in the process
static Calendar start_cal = Calendar.getInstance(); // current day when the program is executed
static Calendar end_cal = Calendar.getInstance(); //end date that the user inputs
static SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
public static boolean date_validation(String date) //partial validation: whether the input date is in a correct format
Date test_date;
try
test_date = format.parse(date);
catch (ParseException e)
return false;
return true;
//created list of dates that are of the same day of the week (for example all Sundays)
static private List<Calendar> getListOfDates()
List<Calendar> dates = new ArrayList<>();
while (!((temp_cal.get(Calendar.YEAR)>= end_cal.get(Calendar.YEAR))&&(temp_cal.get(Calendar.MONTH) >= end_cal.get(Calendar.MONTH))&&(temp_cal.get(Calendar.DAY_OF_YEAR) >= end_cal.get(Calendar.DAY_OF_YEAR))))
temp_cal.add(Calendar.DATE, 7);
dates.add(temp_cal);
return dates;
static private void printListOfDates(List<Calendar> dates)
System.out.println(Arrays.toString(dates.toArray()));
public static void main(String[] str) throws ParseException
String end_date = input.next();
while(!(date_validation(end_date)))
end_date = input.next();
end_cal.setTime(format.parse(end_date));
printListOfDates(getListOfDates());
输入:2018/01/01
输出(仅复制一个示例,整个输出只是此示例的几个副本):
java.util.GregorianCalendar[time=1515233525518,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Helsinki",offset=7200000,dstSavings=3600000 ,useDaylight=true,transitions=118,lastRule=java.util.SimpleTimeZone[id=Europe/Helsinki,offset=7200000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=- 1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA =1,YEAR=2018,MONTH=0,WEEK_OF_YEAR=1,WEEK_OF_MONTH=1,DAY_OF_MONTH=6,DAY_OF_YEAR=6,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=12 ,SECOND=5,MILLISECOND=518,ZONE_OFFSET=7200000,DST_OFFSET=0]]
【问题讨论】:
我不能更强烈地建议您避免使用旧的java.util.Calendar
类。您应该在 java.time
包中找到适合您用例的类。
Calendar
有方法before
和after
进行比较
java.time
包中的大多数(如果不是全部)类都实现了Comparable
。
@JoeC 他们通常也有 isBefore
和 isAfter
方法(恕我直言,更具可读性)。
【参考方案1】:
import java.util.Date;
import java.time.*;
import java.text.SimpleDateFormat;
import java.util.*;
public class days
public static void main (String args[])
Scanner input = new Scanner(System.in);
System.out.println("Enter Dates (Start(yyyy/mm/dd)-End)");
//example 2017 1 5 -> 5 jan 2017
getDates(Integer.parseInt(input.next()),Integer.parseInt(input.next()),
Integer.parseInt(input.next()),Integer.parseInt(input.next()),
Integer.parseInt(input.next()),Integer.parseInt(input.next()));
/*the input needed example
* 2017
* 1
* 1 -Start date
* 2017
* 2
* 10 -End date
*/
public static void getDates(int pYearStart, int pMonthStart, int pDayStart,
int pYearEnd, int pMonthEnd, int pDayEnd)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy MMM dd");
int year = pYearStart;
int month = pMonthStart-1;
int day = pDayStart;
Calendar start = new GregorianCalendar(year,month,day);
int yearEnd = pYearEnd;
int monthEnd = pMonthEnd-1;
int dayEnd = pDayEnd;
Calendar end = new GregorianCalendar(yearEnd,monthEnd,dayEnd);
System.out.print("Start Date: ");
System.out.println(sdf.format(start.getTime()));
System.out.print("End Date: ");
System.out.println(sdf.format(end.getTime()));
System.out.println("");
System.out.println("All Dates:");
boolean sameDate = false;
int amount = 0;
do
System.out.println(sdf.format(start.getTime()));
start.add(Calendar.DAY_OF_MONTH, 7);
amount++;
if(start.get(Calendar.DAY_OF_MONTH) >= end.get(Calendar.DAY_OF_MONTH) &&
start.get(Calendar.MONTH) == end.get(Calendar.MONTH))
sameDate = true;
while(sameDate != true);
System.out.println("No of dates: "+amount);
我想这就是你想要的,我没有使用列表,而是根据你的喜好更改它。
【讨论】:
【参考方案2】:我不确定这是否适合您(我将把它作为一项任务留给您),但您可以使用 LocalDate 执行类似的操作:
import java.util.Scanner;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
class Main
public static void main(String[] args)
Scanner scanner = new Scanner(System.in);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate endDate;
while(true)
System.out.print("Enter the endDate in the format of yyyy/MM/dd:");
String date = scanner.next();
try
endDate = LocalDate.parse(date, formatter);
break;
catch (Exception e)
System.err.println("ERROR: Please input the date in the correct format");
System.out.println("Below are the days between the current day and " + endDate);
printDaysBetween(endDate);
public static void printDaysBetween(LocalDate end)
LocalDate start = LocalDate.now();
while (!start.isAfter(end))
System.out.println(start);
start = start.plusDays(7);
示例用法:
Enter the endDate in the format of yyyy/MM/dd: 2017-10-30
ERROR: Please input the date in the correct format
Enter the endDate in the format of yyyy/MM/dd: 2017/10/30
Below are the days between the current day and 2017-10-30
2017-09-30
2017-10-07
2017-10-14
2017-10-21
2017-10-28
【讨论】:
【参考方案3】:第一个问题是打印结果的方式:
System.out.println(Arrays.toString(dates.toArray()));
如果您想要格式化日期,则需要使用格式化程序。
private static SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd");
static private void printListOfDates(List<Calendar> dates)
for (Calendar date : dates)
System.out.println(outputFormat.format(date));
第二个问题是您似乎在 getListOfDates 的循环中重用了相同的 temp_cal 对象。这会导致您的列表包含同一日历对象的多个副本(多次修改)。您需要为循环中的每次迭代创建一个新实例。
【讨论】:
以上是关于列表中的日历类型元素的主要内容,如果未能解决你的问题,请参考以下文章
SharePoint Server 2019 中的日历列表视图