Android Studio 两个日期选择对话框 设置开始时间和结束时间

需求:

在一个打卡挑战的软件中

作为一个用户,我可以选择开始时间,结束时间,计算时间间隔,以便我可以知道我需要从什么时间开始,什么时间结束

逻辑:

1. 有两个时间选择对话框,可以选择两个不同的日期

2. 开始时间默认为今天,不能选择之前的时间(不能挑战之前的日期)

3. 结束时间默认和开始时间一致

4. 两者均选择后计算时间间隔,如果开始时间与结束时间相同,则间隔为1(今天也算一天,可以打卡)

5. 开始时间不能大于结束时间,如果出现此情况,例如结束时间选择了2024-9-1,开始时间选择了2024-9-15,则将结束时间同时设置为2024-9-15

页面效果:

页面布局:

代码:

activity_date_picker_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <Button
        android:id="@+id/btn_datePickerDialog_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="请选择开始日期"
        android:textSize="30sp"/>

    <TextView
        android:id="@+id/tv_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="这里显示选择的开始日期"
        android:textSize="30sp"/>

    <Button
        android:id="@+id/btn_datePickerDialog_stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="请选择结束日期"
        android:textSize="30sp"/>

    <TextView
        android:id="@+id/tv_stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="这里显示选择的结束日期"
        android:textSize="30sp"/>

    <TextView
        android:id="@+id/tv_difference"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="这里显示开始到结束的总天数"
        android:textSize="30sp"/>

</LinearLayout>

DatePickerDialogActivity.java
package com.example.myapplication;

import android.app.DatePickerDialog;
import android.app.Dialog;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;

import androidx.activity.EdgeToEdge;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class DatePickerDialogActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "error";
    private TextView tv_start;
    private TextView tv_stop;
    private TextView tv_difference;
    private int year;
    private int month;
    private int day;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_date_picker_dialog);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        //设置两个按钮的点击事件
        findViewById(R.id.btn_datePickerDialog_start).setOnClickListener(this);
        findViewById(R.id.btn_datePickerDialog_stop).setOnClickListener(this);

        //获取三个textview
        tv_start = findViewById(R.id.tv_start);
        tv_stop = findViewById(R.id.tv_stop);
        tv_difference = findViewById(R.id.tv_difference);

        //获取当前时间的年月日
        Calendar calendar = Calendar.getInstance();
        year = calendar.get(Calendar.YEAR);
        month = calendar.get(Calendar.MONTH);
        day = calendar.get(Calendar.DAY_OF_MONTH);
        //设置格式为yyyy-MM-dd
        String startTime = String.format(Locale.getDefault(),"%d-%02d-%02d", year, month+1, day);
        //设置开始时间和结束时间为今天
        tv_start.setText(startTime);
        tv_stop.setText(startTime);
        //计算两者的间隔 数字+1 (开始日期为9月1日 结束日期为9月1日也算间隔1天)
        tv_difference.setText(daysBetween());
    }


    

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.btn_datePickerDialog_start){
            //创建开始日期的DatePickerDialog对象,默认选择的日期是今天
            DatePickerDialog dialog = new DatePickerDialog(this, dateSetListener, year, month,day);
            //设置日期选择对话框的最小时间为今天,不能选以前的时间
            dialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
            dialog.show();
        } else if (view.getId() == R.id.btn_datePickerDialog_stop) {
            //获取开始日期中选择的日期
            String dateString = tv_start.getText().toString();
            //以下是为了设置默认选中日期为开始日期选择的日期
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
            try {
                Date date = formatter.parse(dateString);
                Calendar calendar = Calendar.getInstance();
                if (date != null) {
                    calendar.setTime(date);
                }
                int newYear = calendar.get(Calendar.YEAR);
                int newMonth = calendar.get(Calendar.MONTH);
                int newDay = calendar.get(Calendar.DAY_OF_MONTH);

                //创建结束日期的DatePickerDialog对象,默认选择的日期是开始日期中选择的日期
                DatePickerDialog dialog = new DatePickerDialog(this, dateSetListener2, newYear, newMonth, newDay);
                dialog.getDatePicker().setMinDate(calendar.getTimeInMillis());
                dialog.show();
            } catch (ParseException e) {
                Log.d(TAG, "error");
            }
        }
    }


    // 创建开始日期选择对话框的监听器
    DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            //这里是点击日期对话框的确定按钮后做的事情

            String dateString = String.format(Locale.getDefault(),"%d-%02d-%02d", year, monthOfYear+1, dayOfMonth);
            tv_start.setText(dateString);
            // 如果开始日期在结束日期之后,将结束日期设置为同样的日期
            if (isDateAfterEndDate(year, monthOfYear, dayOfMonth)){
                tv_stop.setText(dateString);
            }
            tv_difference.setText(daysBetween());


        }
    };

    // 创建结束日期选择对话框的监听器
    DatePickerDialog.OnDateSetListener dateSetListener2 = new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            String dateString = String.format(Locale.getDefault(),"%d-%02d-%02d", year, monthOfYear+1, dayOfMonth);
            tv_stop.setText(dateString);
            tv_difference.setText(daysBetween());
        }
    };


    // 判断选择的日期是否在结束日期之后
    private boolean isDateAfterEndDate(int year, int month, int day) {
        month++;
        String dateString2 = tv_stop.getText().toString();
        String[] dateArr2 = dateString2.split("-");
        int year2 = Integer.parseInt(dateArr2[0]);
        int month2 = Integer.parseInt(dateArr2[1]);
        int day2 = Integer.parseInt(dateArr2[2]);
        return (year > year2) ||
                (year == year2 && month > month2) ||
                (year == year2 && month == month2 && day > day2);
    }

    //计算间隔
    private String daysBetween(){
        String dateString1 = tv_start.getText().toString();
        String dateString2 = tv_stop.getText().toString();
        String[] dateArr1 = dateString1.split("-");
        int year1 = Integer.parseInt(dateArr1[0]);
        int month1 = Integer.parseInt(dateArr1[1]);
        int day1 = Integer.parseInt(dateArr1[2]);
        String[] dateArr2 = dateString2.split("-");
        int year2 = Integer.parseInt(dateArr2[0]);
        int month2 = Integer.parseInt(dateArr2[1]);
        int day2 = Integer.parseInt(dateArr2[2]);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDateTime date1 = LocalDateTime.of(year1,month1,day1,0,0,0);
        LocalDateTime date2 = LocalDateTime.of(year2,month2,day2,0,0,0);

        // 计算两个日期之间的天数
        String diffString = String.valueOf(ChronoUnit.DAYS.between(date1, date2) + 1);
        return "时间间隔为:" + diffString;
    }


}

刚开始写,有很多地方写的比较臃肿,欢迎大家指正

Android Studio选择时间日期通常涉及到使用`DatePicker`和`TimePicker`组件,以及`Calendar`类或`java.time`包提供的API。以下是一个简单的示例: ```java // 导入所需的库 import android.app.DatePickerDialog; import android.app.TimePickerDialog; import android.os.Bundle; import android.widget.Button; import android.widget.CalendarView; import android.widget.DatePicker; import android.widget.TextView; import android.widget.TimePicker; public class MainActivity extends AppCompatActivity { private TextView dateTextView; private TextView timeTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化UI元素 dateTextView = findViewById(R.id.date_text_view); timeTextView = findViewById(R.id.time_text_view); // 创建按钮以显示日期选择对话框 Button datePickerButton = findViewById(R.id.date_picker_button); datePickerButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showDatePicker(); } }); // 创建按钮以显示时间选择对话框 Button timePickerButton = findViewById(R.id.time_picker_button); timePickerButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showTimePicker(); } }); } private void showDatePicker() { DatePickerDialog dialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { String formattedDate = String.format("%04d-%02d-%02d", year, month + 1, dayOfMonth); // 注意月份是从0开始计数的 dateTextView.setText(formattedDate); } }, Calendar.getInstance().get(Calendar.YEAR), Calendar.getInstance().get(Calendar.MONTH), Calendar.getInstance().get(Calendar.DAY_OF_MONTH)); dialog.show(); } private void showTimePicker() { TimePickerDialog dialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() { @Override public void onTimeSet(TimePicker view, int hourOfDay, int minute) { String formattedTime = String.format("%02d:%02d", hourOfDay, minute); timeTextView.setText(formattedTime); } }, Calendar.getInstance().get(Calendar.HOUR_OF_DAY), Calendar.getInstance().get(Calendar.MINUTE), false /* 是否显示秒针 */); dialog.show(); } } ``` 在这个例子中,我们创建了两个按钮分别触发日期时间选择,并处理回调函数将用户选择日期时间显示在相应的TextView上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值