日期时间是一个值
日期时间值几乎总是在软件中作为单个值进行跟踪。从技术上讲,它们在内部表示为自 epoch 以来的秒/毫秒/微秒/纳秒计数。
您可能希望在用户界面中单独显示日期和时间,而不是在内部显示。
此外,您几乎可以肯定应该考虑时区。天真的程序员通常认为他们可以忽略时区,但这几乎肯定会在以后引起痛苦。
了解您的数据库对日期时间的处理
不同的数据库处理日期时间的方式不同。阅读文档、玩转、试验并准确了解数据库的工作原理是绝对重要的。
Postgres 对日期时间有出色而明智的处理。即使您使用其他数据库,请参阅 date-time data types 和 date-time functions(命令)上出色的 Postgres 文档,以了解各种问题以及 SQL 标准定义的内容与数据库特有的内容。
全球存储,本地展示
日期时间是一个令人惊讶的复杂和复杂的问题。控制问题的一个关键是在UTC 中工作。以 UTC 格式将您的日期时间值存储在数据库(或序列化文件或 XML/JSON 通信)中。用 UTC 编写大部分业务逻辑,除了本地时区很重要,例如定义“新一天的开始”。
当您向用户展示时,请使用 ISO 8601 格式或本地化到他们自己的时区(或他们期望的时区)。这遵循了国际化/本地化的基本思想。对于文本值,您在代码中使用某些键字符串。在用户界面中呈现时,您将这些内部字符串映射到用户界面的本地化(翻译)文本值。一些带有日期时间:内部 UTC,用户界面中的本地时区。
一个警告:您可能希望还存储一个本地日期时间以记录历史。由于政客和官僚,时区规则经常和反复无常地变化。您的软件的时区数据库可能已过期。因此,您可能希望存储您或用户认为是某个日期时间的内容然后。但不要依赖它;确定并存储 UTC 值。
提示:学会在 24 小时内思考和阅读。您作为程序员/调试器/系统管理员的生活将变得更加轻松且不易出错。
Joda-Time 或 java.time
Java 捆绑的 java.util.Date 和 .Calendar 类是出了名的麻烦。避开他们。
改为使用 Joda-Time 或 Java 8 中内置的新 java.time package(受 JSR 310 定义的 Joda-Time 启发)。
两个库都使用 ISO 8601 格式作为其默认格式,用于解析和生成字符串。
ISO 8601
ISO 8601 是一个明智的标准,它定义了如何以特定且明确的文本格式呈现日期时间值、时区和偏移量、持续时间和时段。研究那个写得很好的维基百科页面。
请特别注意标准所称的Durations。时间跨度以这种格式定义:PnYnMnDTnHnMnS 其中P 表示“期间”,T 将日期部分与时间部分分开,其他可选部分是数字+字母。半小时的约会将是PT30M。这对您来说可能很方便,例如下面我的ERD 中的“period_”字段。在 Joda-Time 中,Period 类通过跟踪其月、日、小时等来表示时间跨度,并且知道如何解析和生成这种格式的字符串。
半开
您可以选择以两种方式之一来存储约会。一种方法是开始日期时间和持续时间(90 分钟、20 分钟等)。另一种方法是记录开始和停止日期时间。在这种情况下,通常和通常最好的方法称为“半开”。这意味着开头是inclusive,而结尾是exclusive。
例如,一个小时的约会将从 11:00 到 12:00,这意味着“从上午 11 点开始,一直到但不包括下一小时的第一刻(中午) ”。下一次约会将从 12:00 到 13:00。
在 StackOverflow 中搜索“Half-open”以查找更多讨论、示例和图表。
多对多
Patient 和 Doctor 之间的关系就是我们所说的Many-To-Many。一个医生看很多病人,一个病人可能看不止一个医生。确保您了解关系数据库设计中的多对多表。解决方案总是添加第三个表,有时称为“桥”表,作为其他父表的子表。在您的情况下,Appointment 表是桥接表。
您需要知道如何跨多对多关系执行联接。
直接 SQL
如果您是编程新手或关系数据库新手,我建议您避免使用 Hibernate。你真的应该了解正在发生的事情。 Hibernate 有一些适当的用途。但如果你认为 Hibernate 会神奇地让数据库问题消失,你会失望的。
属性
属性由你决定。它们取决于您要解决的业务(或家庭作业?)问题。你有基本的权利。
约会安排是一个非常困难的业务问题,要编写软件来解决。例如,您是否只是记录约会?或者您是否通过创建预定义的时间段来跟踪医生的可用性,如果是,您如何处理每个医生日历的异常和更改?您需要编写非常具体的需求和用例。用户的期望很容易超出您的预期要求。
这是一个简单的视图。