挪威出生证号码使用Long还是String类型?

4

我有一个名为Person的类,大致如下:

public abstract class Person {
    private String birthNo;
    ...
}

挪威出生证号码为11位,并采用此维基百科页面所述的算法构建。我不能使用int,因为大多数出生证号码超过Integer.MAX_VALUE
我听说在决定是否应该使用String或整数来存储数字值时,你应该问自己:我需要对这个值执行数学运算吗?
我正在对birthNo执行此操作,但是很多操作使用String的charAt(int i)会更容易一些。如果我将出生证号码存储为long,我将不得不使用模数和除法来获取所需的数字: int ninth = Character.getNumericValue(birthNo.charAt(8));int ninth = birthNo / 100 % 10 我想要进行的数学运算是获取人的性别(如果第九位数字为偶数,则为女性),并使用类似于ISBN的算法验证出生证号码。
使用String的另一个理由是,某些出生证号码可能具有前导零,因此如果将其存储为long,则不会是“11位数字”。
什么是首选解决方案?对于数学运算,使用Long还是为了方便使用String?
3个回答

3
挪威的11位出生编号在出生时或注册国家人口登记处时分配。该登记由挪威税务局维护。它由出生日期(DDMMYY)、三位数字个人编号和两个检查位组成。
我建议创建一个 BirthNumber 类,其中包含 LocalDate 作为出生日期,而其他两个字段则根据需要使用 int 或 String 值。这样,您可以在构造函数中解析出生编号,并使用实例方法获取所需的值。
根据下面的评论,以下是如何封装出生日期的方式:
import java.time.LocalDate;

public class DNumberLocalDate {

    private final LocalDate localDate;
    private final boolean isDNumber;

    public DNumberLocalDate(LocalDate localDate, boolean isDNumber) {
        this.localDate = localDate;
        this.isDNumber = isDNumber;
    }

    public DNumberLocalDate(LocalDate localDate) {
        this(localDate, false);
    }

    public int getDayOfMonth() {
        return isDNumber ? localDate.getDayOfMonth() + 40 : localDate.getDayOfMonth();
    }

}

我能看到这个解决方案的一个问题是,并不是所有的出生数字都能表示为“日期”。请参见此链接中列表中的第三项。 - Martin M J
听起来像是一个复杂的系统。也许你可以以不同的方式存储D数字,或者使用某种标志,或者为LocalDate创建一个包装类来处理这个问题。 - Robert Bain
我认为我会给Person类添加getBirthNumberAsLonggetBirthNumberAsString方法。或者创建一个BirthNumber类,其中包含asLong/asString方法。然后如何存储就不重要了。 - Holloway
我将提供一个示例,说明如何考虑包装出生日期以与D号码一起使用。 - Robert Bain
@RobertBain 我认为你的意思是如果是D-number,getDayOfMonth()方法应该返回40 + localDate.getDayOfMonth() - Martin M J
@MartinMJ 谢谢,已更新。 - Robert Bain

2
出生编号是身份证明,但它不是数字:您不希望对其进行数学运算。在您的例子中,您想要拆分身份证以查找一些信息,而不是将其除以某个数。因此,您应该使用 String。另一个原因是前导零,正常数字无法处理它。
但是,您可以使用 BigDecimalBigInteger 来处理大数字。

我正在使用数学运算来获取个人的性别(如果第9个数字为偶数则为女性,否则为男性),并验证出生编号。 - Martin M J
2
@MartinMJ 你可以通过获取字符并检查其值模2来获得性别。这将忽略对ID的直接数学运算。 - Turing85
我明白了。我误以为@Happy的意思是完全不进行任何数学运算。 - Martin M J
我同意Happy的观点,这个人的ID号码实际上是一个“标签”,而不是数字,因此使用String类型更为合适。如果ID以0开头怎么办?如果将其存储为long类型,则无法捕获该情况。就像电话号码实际上是标签而不是真正的数字,不应该存储在数字类型中。 - Jesper

-1
一个字符串可以表示比基本整数更多的内容(前导0和更多) 因此,你应该将其存储为字符串并设置为私有的。 你可以定义两个getter方法,每个类型都有一个。 如果想要具有面向对象的代码,就不要直接访问变量。 问候。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接