学习应该怎么学——以学生的一个打印月历练习为例

Java程序设计课程中有一个练习任务:在控制台输出指定年月的月历。完成任务的一个要点是获取指定年月的1号是周几。老师给的实现案例里用的是Calendar类的get方法。一个学生自己想了别的办法实现——自己指定一个日期作为参考点,计算1号到这个参考点间隔的天数,从而推算出1号是周几。并且将实现代码封装成了类,提供了多种构造方法,包括用字符串参数构建Calendar对象,通过正则表达式解析字符串,得到年月日。

通过这个练习,反映了该同学主动学习、主动思考、愿意创新的学习态度。不机械的照抄老师给的答案,能想出新的思路,灵活运用自己学到的知识,解决实际问题。这才是大学生该有的学习态度。

编程不是背书,而是用编程语言表达自己的思想。所以,你得有思想、有想法、有思路、会表达。平时这样练习多了,慢慢就会了。不愿意思考,不愿意实践是学不好编程的。

下面是该同学的代码原样。

package org.example;

import java.time.LocalDate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MonthlyCalendar {
  //  成员属性

  // 定义判断标准(周一),日期比对全部以此为标准
  private static final LocalDate DEFAULT_DATE = LocalDate.of(2024, 1, 1);
  // 定义列表,存储每个月包含的天数
  int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  //  定义当前时间

  // 无参传递,默认为当前时间
  private LocalDate usertime=LocalDate.now();


  //  构造函数
  public MonthlyCalendar() {
    // 无参传递,默认为当前时间
    printCalendar();
  }
  public MonthlyCalendar(String s){
    // 有参传递,用正则分割日期
    Pattern p = Pattern.compile("(\\d{4})-(\\d{1,2})-(\\d{1,2})");
    Matcher m = p.matcher(s);
    if (m.find()){
//      System.out.println(m.group(1)+"\t"+m.group(2)+"\t"+m.group(3));

      // 因为修改日会重置月,所以月份最后修改
      usertime = usertime.withDayOfYear(Integer.parseInt(m.group(3)));
      usertime = usertime.withYear(Integer.parseInt(m.group(1)));
      usertime = usertime.withMonth(Integer.parseInt(m.group(2)));
//      System.out.println(usertime);
      printCalendar();
    }else {
      System.out.println("时间格式有误");
    }
  }


  //  成员方法

  //  打印界面
  private void printCalendar() {
    System.out.println("\n\n\n\n\n时间:"+usertime);
    // 调用函数获取周值
    int startdate = dateDifferent();
    // 判断是否为周日,是的话重置循环次数来确保打印列表周日在前
    startdate = startdate == 7 ? 0 : startdate;
    // 根据当前年份决定2月多少天
    days[1] = leapYear(usertime.getYear()) ? 29 : 28;
    // 定义计数器,用于判断换行
    int count = 0;

    System.out.println("\n日\t\t一\t\t二\t\t三\t\t四\t\t五\t\t六");
    for (int i = 0; i < startdate; i++) {
      System.out.printf("--\t\t");
      count++;
    }
    for (int i = 1; i < days[usertime.getMonthValue() - 1] + 1; i++) {
      System.out.printf(i + "\t\t");
      count++;
      if (count % 7 == 0) {
        System.out.println();
      }
    }
  }

  // 获取时间差
  private int dateDifferent() {
    // 定义开始与结束年月单独存储变量
    int sy, sm, ey, em;
    // 定义存储用户时间在前(决定星期值返回顺序)
    boolean isbig;
    // 判断用户时间位置,true:在前,false:在后
    if (usertime.isBefore(DEFAULT_DATE)) {
      isbig = false;
      System.out.println("用户时间在前");
      sy = usertime.getYear();
      sm = usertime.getMonthValue();
      ey = DEFAULT_DATE.getYear();
      em = DEFAULT_DATE.getMonthValue();
    } else {
      isbig = true;
      System.out.println("用户时间在后");
      sy = DEFAULT_DATE.getYear();
      sm = DEFAULT_DATE.getMonthValue();
      ey = usertime.getYear();
      em = usertime.getMonthValue();
    }

    // 判断年与年之间相差天数
    System.out.println("起始年:" + sy + "\t结束年:" + ey);
    int yearstodays = 0;
    for (int i = sy; i < ey; i++) {
      yearstodays += leapYear(i) ? 366 : 365;
    }
    System.out.println("两年相差天数:" + yearstodays);


//   计算起始年与结束年多余月的天数
    System.out.println("起始月:" + sm + "\t\t结束月:" + em);
    int usedate = 0, nusedate = 0;
    days[1] = leapYear(sy) ? 29 : 28;
    for (int i = 0; i < sm - 1; i++) {
      usedate += days[i];
    }
    days[1] = leapYear(ey) ? 29 : 28;
    for (int i = 0; i < em - 1; i++) {
      nusedate += days[i];
    }
    System.out.println("起始月天数:" + usedate + "\t结束月天数:" + nusedate);

    // 期间时间=两年之间日期-起始年已用日期+结束年未用日期
    int endate = yearstodays - usedate + nusedate;
    System.out.println("两日期相差天数为:" + endate);

    // 返回当月第一天是周几,根据用户时间与基准时间的位置取不同值
    // 前者为用户时间在后,正常返回值
    // 后者为用户时间在前,需要返回7-时间,但是因为未知原因,老是少两天,所以直接返回9-时间解决bug
    return isbig ? endate % 7 + 1 : 9 - (endate % 7 + 1);
  }

  //  判断是否闰年(true:是,false:否)
  private boolean leapYear(int n) {
    return (n % 4 == 0 && n % 100 != 0) || n % 400 == 0;
  }
}
package org.example;

import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
//    System.out.println("请输入一个日期,格式为yyyy-mm-dd:");
//    String date = input.nextLine();
//    有参调用,以当前时间为主
    MonthlyCalendar yl = new MonthlyCalendar("2024-6-1");
//    无参调用,以系统时间为主
    MonthlyCalendar yl2 = new MonthlyCalendar();
  }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

因上精进,果上随缘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值