解析用户在日期类型的编辑文本字段中输入的内容并检查日期格式是否正确

Parsing user input in edittext field of the type date and check for correct date format

我正在开发 Android 应用程序并处理来自 edittext 字段的用户输入。我想检查用户是否输入了正确的日期格式;但是,由于我不明白的原因,我需要将 edittext 类型日期的类型转换为字符串,然后将其转换回浮点数,以检查正则表达式并且无法正常工作。

editactivity.xml:

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

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_normal_text"
        android:hint="Enter the title of your selfie"
        android:inputType="text"
        android:textStyle="bold"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_name"
        android:hint="Enter the title of your selfie"
        android:inputType="text"
        android:textStyle="bold"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/name"
        android:hint="Enter the title of your selfie"
        android:inputType="text"
        android:textStyle="bold"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_location"
        android:hint="Enter the title of your selfie"
        android:inputType="text"
        android:textStyle="bold"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_email_address"
        android:textStyle="bold"
        android:inputType="textEmailAddress"
        android:hint="Enter Email Address"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/ed_date"
        android:hint="Enter Date"
        android:inputType="date"
        android:textStyle="bold"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/location"
        android:hint="Enter Location"
        android:inputType="textAutoComplete"
        android:textStyle="bold"/>

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Submit"
        android:id="@+id/btn_submit" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="match_parent"
        android:layout_height="106dp"
        android:padding="1dp"
        android:layout_weight="0.98"></ImageView>

    <Button
        android:id="@+id/btnCapture"
        android:layout_width="135dp"
        android:layout_height="wrap_content"
        android:text="Take picture" />

    <Button
        android:id="@+id/save"
        android:layout_width="135dp"
        android:layout_height="wrap_content"
        android:text="Save" />

    <Button
        android:id="@+id/cancel"
        android:layout_width="135dp"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="Cancel" />

    <Button
        android:id="@+id/image"
        android:layout_width="135dp"
        android:layout_height="wrap_content"
        android:text="See Image" />

</LinearLayout>

EditActivity:

package gmbh.packagename.myselfieme;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.icu.util.Calendar;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import static gmbh.packagename.myselfieme.R.drawable.marker;
import static gmbh.packagename.myselfieme.R.id.date;
import static gmbh.packagename.myselfieme.R.id.time;
import static gmbh.packagename.myselfieme.R.string.snippet;


public class EditActivity extends Activity {


    public static int count = 0;
    static final int REQUEST_TAKE_PHOTO = 1;
    private static final String KEY_MARKER_ID = "id";
    private static final String KEY_MARKER_TITLE = "title";
    private static final String KEY_MARKER_DATE = "date";
    private static final String KEY_MARKER_LOC = "location";
    private static final String KEY_MARKER_LAT = "latlng";
    private static final String KEY_MARKER_NAME = "name";
    private static final String KEY_MARKER_PIC = "picture";
    private static final int CAMERA_REQUEST = 1888;

    private EditText etNormalText;
    private EditText etName;
    private EditText etLocation;
    private EditText etEmailAddrss;
    private EditText etDate;
    private Button btnSubmit;
    private ImageView imageView;
    Bitmap photo;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.editactivity);
        PostsDatabaseHelper helper = PostsDatabaseHelper.getInstance(this);
        helper.getReadableDatabase();
        registerViews();
        this.imageView = (ImageView) this.findViewById(R.id.imageView1);
        Button photoButton = (Button) this.findViewById(R.id.btnCapture);
        photoButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(cameraIntent, CAMERA_REQUEST);
            }
        });
    }
    private void registerViews() {
        etNormalText = (EditText) findViewById(R.id.et_normal_text);
        etName = (EditText) findViewById(R.id.et_name);
        etLocation = (EditText) findViewById(R.id.et_location);
        // TextWatcher would let us check validation error on the fly
        etNormalText.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {
                Validation.hasText(etNormalText);
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after){}
            public void onTextChanged(CharSequence s, int start, int before, int count){}
        });
        etName.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {
                Validation.hasText(etName);
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after){}
            public void onTextChanged(CharSequence s, int start, int before, int count){}
        });
        etLocation.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {
                Validation.hasText(etLocation);
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after){}
            public void onTextChanged(CharSequence s, int start, int before, int count){}
        });
        etEmailAddrss = (EditText) findViewById(R.id.et_email_address);
        etEmailAddrss.addTextChangedListener(new TextWatcher() {
            // after every change has been made to this editText, we would like to check validity
            public void afterTextChanged(Editable s) {
                Validation.isEmailAddress(etEmailAddrss, true);
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after){}
            public void onTextChanged(CharSequence s, int start, int before, int count){}
        });

        etDate = (EditText) findViewById(R.id.ed_date);
        etDate.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {
                Validation.isDate(etDate, false);
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after){}
            public void onTextChanged(CharSequence s, int start, int before, int count){}
        });

        btnSubmit = (Button) findViewById(R.id.btn_submit);
        btnSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Log.w("EditActivity", "clicking on btn_submit");
                /*
                Validation class will check the error and display the error on respective fields
                but it won't resist the form submission, so we need to check again before submit
                 */
                if ( checkValidation () )
                    submitForm();
                else
                    Toast.makeText(EditActivity.this, "Form contains error", Toast.LENGTH_LONG).show();
            }
        });

        final LatLng latlng = getIntent().getParcelableExtra("location");
        final EditText title = (EditText) findViewById(R.id.title);
        final EditText date = (EditText) findViewById(R.id.ed_date);
        final EditText location = (EditText) findViewById(R.id.location);
        final EditText name = (EditText) findViewById(R.id.name);
        Button button = (Button) findViewById(R.id.save);
        Button cancelbutton = (Button) findViewById(R.id.cancel);
        Button imagebutton = (Button) findViewById(R.id.image);


        imagebutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent myIntent = new Intent(EditActivity.this, ImageActivity.class);
                myIntent.putExtra("marker", marker);
                myIntent.putExtra("BitmapImage", photo);
                EditActivity.this.startActivity(myIntent);
                setResult(Activity.RESULT_OK, myIntent);
            }
        });

        date.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(date.getText().length()<1){
                    // Display toast
                    Toast.makeText(getApplicationContext(), "Please enter something !",Toast.LENGTH_LONG).show();
                }

            }

        });

        date.addTextChangedListener(new TextWatcher(){

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                                          int after) {
                if(date.getText().length()<1){
                    // Display toast
                    Toast.makeText(getApplicationContext(), "Please enter something !",Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                                      int count) {

            }
            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
                //String ss = date.getText().toString();
                int o = 0;

                //String regEx ="^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d{2}$";

                /*
                                if ((ss.charAt(2) == '/') && (ss.charAt(4) == '/')) {

                                }*/
                int ss = date.getInputType();

                if (ss == (InputType.TYPE_CLASS_DATETIME | InputType.TYPE_DATETIME_VARIATION_DATE))
                {
                    int dateInput = Integer.parseInt(date.getText().toString());

                    //(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\d\d)

                    Toast.makeText(EditActivity.this, "Format Is right", Toast.LENGTH_LONG).show();
                }

               /* if (ss.matches("\d{4}-\d{2}-\d{2}")) {
                    Toast.makeText(EditActivity.this, "Format Is right", Toast.LENGTH_LONG).show();
                }*/
                /*if(date.getText().length()<4){
                    // Display toast
                    Toast.makeText(getApplicationContext(), "Please enter something !",Toast.LENGTH_LONG).show();
                }*/
                else {
                    date.setTextColor(Color.RED);
                    date.setText("Invalid Format");
                }
                //ss = "";
            }
        });


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View view) {
                Bitmap resized = Bitmap.createScaledBitmap(photo, (int) (photo.getWidth() * 0.5), (int) (photo.getHeight() * 0.5), true);

                //Bitmap.Config conf = Bitmap.Config.ARGB_8888;
                //Bitmap bmp = Bitmap.createBitmap(150, 150, conf);
                Canvas canvas1 = new Canvas();
                Rect rectangle = new Rect(0,0,100,100);
                canvas1.drawBitmap(resized, new Rect(0,0,100,100), rectangle, null);
                resized = addBorderToBitmap(resized, 10, Color.WHITE);
                // Add a border around the bitmap as shadow
                resized = addBorderToBitmap(resized, 3, Color.LTGRAY);
                MarkerOptions marker = new MarkerOptions().position(latlng)
                        .icon(BitmapDescriptorFactory.fromBitmap(resized))
                        .draggable(true);
                if (title.getText() != null) {

                    marker.title(title.getText().toString());
                }
                if( date.getText().toString().length() == 0 )
                    date.setError( "date is required!" );
                marker.snippet(date.getText().toString());
                if (name.getText() !=null) {
                    marker.snippet(name.getText().toString());
                }
                if (location.getText() !=null) {
                    marker.snippet(location.getText().toString());
                }
                Intent resultIntent = new Intent();
                resultIntent.putExtra("marker", marker);
                resultIntent.putExtra("BitmapImage", photo); // passing the bitmap to the next activity . and retrieve it to the next activity
                setResult(Activity.RESULT_OK, resultIntent);
                finish();
            }

        });}

    public static Bitmap overlay(Bitmap bmp, Bitmap resized) {
        Bitmap bmOverlay = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
        Canvas canvas = new Canvas(bmOverlay);
        canvas.drawBitmap(bmp, new Matrix(), null);
        canvas.drawBitmap(resized, 0, 0, null);
        return bmOverlay;
    }

    private void submitForm() {
        // Submit your form here. your form is valid
        Toast.makeText(this, "Submitting form...", Toast.LENGTH_LONG).show();
        Log.w("EditActivity", "submitForm");
    }

    private boolean checkValidation() {
        Log.w("EditActivity", "checkValidation");
        boolean ret = true;

        if (!Validation.hasText(etNormalText)) ret = false;
        if (!Validation.isEmailAddress(etEmailAddrss, true)) ret = false;
        if (!Validation.isDate(etDate, false)) ret = false;
        return ret;

    }


    public void onClick(View v) {
        // TODO:
        // Launch Activity Two
        // Hint: use Context's startActivity() method
        // Create an intent stating which Activity you would like to start
        Intent myIntent = new Intent(EditActivity.this, MapsActivity.class);

        // Launch the Activity using the intent
        EditActivity.this.startActivity(myIntent);
    }

    protected Bitmap addBorderToBitmap(Bitmap resized, int borderWidth, int borderColor) {
        // Initialize a new Bitmap to make it bordered bitmap
        Bitmap dstBitmap = Bitmap.createBitmap(
                resized.getWidth() + borderWidth * 2, // Width
                resized.getHeight() + borderWidth * 2, // Height
                Bitmap.Config.ARGB_8888 // Config
        );

        /*
            Canvas
                The Canvas class holds the "draw" calls. To draw something, you need 4 basic
                components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing
                into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint
                (to describe the colors and styles for the drawing).
        */
        // Initialize a new Canvas instance
        Canvas canvas = new Canvas(dstBitmap);

        // Initialize a new Paint instance to draw border
        Paint paint = new Paint();
        paint.setColor(borderColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(borderWidth);
        paint.setAntiAlias(true);
        Rect rect = new Rect(
                borderWidth / 2,
                borderWidth / 2,
                canvas.getWidth() - borderWidth / 2,
                canvas.getHeight() - borderWidth / 2
        );

          // Draw a rectangle as a border/shadow on canvas
        canvas.drawRect(rect, paint);

        // Draw source bitmap to canvas
        canvas.drawBitmap(resized, borderWidth, borderWidth, null);
            resized.recycle();
            // Return the bordered circular bitmap
            return dstBitmap;
   }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
            photo = (Bitmap) data.getExtras().get("data");
            this.imageView.setImageBitmap(photo);
        }
    }

}

问题出在这段代码中:

@Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
                //String ss = date.getText().toString();
                int o = 0;

                //String regEx ="^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d{2}$";

                /*
                                if ((ss.charAt(2) == '/') && (ss.charAt(4) == '/')) {

                                }*/
                int ss = date.getInputType();

                if (ss == (InputType.TYPE_CLASS_DATETIME | InputType.TYPE_DATETIME_VARIATION_DATE))
                {
                    int dateInput = Integer.parseInt(date.getText().toString());

                    //(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\d\d)

                    Toast.makeText(EditActivity.this, "Format Is right", Toast.LENGTH_LONG).show();
                }

               /* if (ss.matches("\d{4}-\d{2}-\d{2}")) {
                    Toast.makeText(EditActivity.this, "Format Is right", Toast.LENGTH_LONG).show();
                }*/
                /*if(date.getText().length()<4){
                    // Display toast
                    Toast.makeText(getApplicationContext(), "Please enter something !",Toast.LENGTH_LONG).show();
                }*/
                else {
                    date.setTextColor(Color.RED);
                    date.setText("Invalid Format");
                }
                //ss = "";
            }
        });

这是validation.java:

package gmbh.package.myselfieme;

import android.widget.EditText;
import java.util.regex.Pattern;

public class Validation {

    // Regular Expression
    // you can change the expression based on your need
    private static final String EMAIL_REGEX = "^[_A-Za-z0-9-\+]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$";
    private static final String DATE_REGEX = "^\d{4}-\d{2}-\d{2}$";

    // Error Messages
    private static final String REQUIRED_MSG = "required";
    private static final String EMAIL_MSG = "invalid email";
    private static final String DATE_MSG = "###-#######";

    // call this method when you need to check email validation
    public static boolean isEmailAddress(EditText editText, boolean required) {
        return isValid(editText, EMAIL_REGEX, EMAIL_MSG, required);
    }

    // call this method when you need to check phone number validation
    public static boolean isDate(EditText editText, boolean required) {
        return isValid(editText, DATE_REGEX, DATE_MSG, required);
    }

    // return true if the input field is valid, based on the parameter passed
    public static boolean isValid(EditText editText, String regex, String errMsg, boolean required) {

        String text = editText.getText().toString().trim();
        // clearing the error, if it was previously set by some other values
        editText.setError(null);

        // text required and editText is blank, so return false
        if ( required && !hasText(editText) ) return false;

        // pattern doesn't match so returning false
        if (required && !Pattern.matches(regex, text)) {
            editText.setError(errMsg);
            return false;
        };

        return true;
    }

    // check the input field has any text or not
    // return true if it contains text otherwise false
    public static boolean hasText(EditText editText) {

        String text = editText.getText().toString().trim();
        editText.setError(null);

        // length 0 means there is no text
        if (text.length() == 0) {
            editText.setError(REQUIRED_MSG);
            return false;
        }

        return true;
    }
}

这是错误信息:

  Process: gmbh.packagename.myselfieme, PID: 17795
                                                                            java.lang.NumberFormatException: Invalid int: "2505250525"
                                                                                at java.lang.Integer.invalidInt(Integer.java:138)
                                                                                at java.lang.Integer.parse(Integer.java:413)
                                                                                at java.lang.Integer.parseInt(Integer.java:367)
                                                                                at java.lang.Integer.parseInt(Integer.java:334)
                                                                                at gmbh.packagename.myselfieme.EditActivity.afterTextChanged(EditActivity.java:203)

实际上,为什么我需要读取日期输入类型的输入,将其转换为整数并检查该整数值的格式是否正确?没有其他更好的方法吗?我只想检查用户输入的数字是否超过 6 位,以及这些数字的格式是否正确。

如有任何提示或帮助,我们将不胜感激,谢谢!

I just want to check that the users does not enter more than 6 digits and that these digits have the right format.

比方说,要求的格式是 dd-mm-yy

使用正则表达式 - \d{2}-\d{2}-\d{2}

例如,

if (inputSTR.matches("\d{2}-\d{2}-\d{2}")) {
    // input matches to required pattern
} else {
    // Show error msg
}

首先, 您应该使用日期选择器而不是 EditText 可能值得考虑。

无论如何,如果您将日期作为字符串获取,推荐的验证方法是尝试将其解析为日期并查看是否成功——而不是通过正则表达式。而且您当然不应该尝试将其解析为整数,这注定会失败。我的代码会是这样的:

    String ss = date.getText().toString();
    if (ss.isEmpty()) {
        // tell the user to enter something
    } else {
        try {
            LocalDate.parse(ss);
            // tell the user the format is right
        } catch (DateTimeParseException dtpe) {
            // tell the user that this is not a valid date
        }
    }

我假设您的日期格式应为 yyyy-MM-dd。这是 LocalDate 的默认解析格式,因此如果您了解异常和 try/catch 构造,它会相当简单。如果您需要不同的格式,您将需要通过 DateTimeFormatter.

来指定它

与正则表达式方法相比的优势在于它可以为您提供更好的验证。 ^\d{4}-\d{2}-\d{2}$ 将接受 2017-29-11 和 2017-11-92 作为日期,如果月份不是 1 到 12 或日期不在那个月。

现在开始了,如果您需要保留日期(可能是因为您要求用户输入日期),请将其保留为 LocalDate 对象而不是字符串。这将使您的应用准备好在日期执行各种操作。每当您需要字符串时,只需使用 LocalDate.toString()。或者使用 DateTimeFormatter 如果您想要字符串,例如“2017 年 11 月 19 日星期日”,甚至是德语或其他语言。

我正在使用 java.time,现代 Java 日期和时间 API 也称为 JSR-310。不幸的是,大多数 Android 设备尚未配备此功能。解决方案是 ThreeTenABP,将 JSR-310 向后移植到 Android。我鼓励你得到这个并开始编码。