Repository: time-rs/time (language: rust)

Issue:
Upgrading to rand 0.8
A new version of the [`rand`](https://github.com/rust-random/rand/blob/master/CHANGELOG.md#080---2020-12-18) crate has been released. While the changes needed to upgrade `time` itself are trivial, `quickcheck` still depends on `rand` 0.7.3 and it is unclear when a new version will be released (although there's already a PR at BurntSushi/quickcheck#264).

It is technically possible to rely on both 0.7.3 (for `quickcheck`) and 0.8.0 (for everything else) by doing something like this:
```toml
[dependencies]
rand = { version = "0.8.0", optional = true, default-features = false }
rand-07 = { package = "rand", version = "0.7.3", optional = true, default-features = false }

[features]
quickcheck = ["quickcheck-dep", "rand-07", "std"]
```
Although it's not very pretty. I'll submit a PR to give a better idea of what the changes look like.

MSRV is not affected, since `rand` 0.8 supports Rust >=1.36.
Upgrade to quickcheck 1.0
The time crate should upgrade the quickcheck dependency to 1.0 prior to time's 0.3 release. The API is largely similar, but there are some changes. Notably, it is no longer possible (for the time, see BurntSushi/quickcheck#267) to generate a value within a given range. This can be worked around with the following function. It has some limitations with regard to overflow within the type, but I don't believe that should be an issue for any values used in the time crate.

```rust
fn arbitrary_between<T>(g: &mut Gen, min: T, max: T) -> T
where
    T: PartialOrd
        + AddAssign
        + Add<Output = T>
        + Sub<Output = T>
        + Rem<Output = T>
        + Arbitrary
        + Copy,
{
    #[allow(clippy::eq_op)]
    let zero = min - min;

    let range = max - min;
    let mut within_range = T::arbitrary(g) % range;

    if within_range < zero {
        within_range += range;
    }

    within_range + min
}
```

One thing I noticed in the documentation that I didn't before (I'm not sure if it was present or not and can't be bothered to check) is that the `Gen::size()` method _does not need to be used_, as all types in the time crate have a constant size; the example used as a use case is `Vec`, which most certainly does not. As such, the entire `foo_respects_generator_size` and `test_generator_size!` bit can be dropped, I believe.

This should likely be done in coordination with #299, though it's not strictly necessary. That change by itself will be nearly trivial.

cc @emlun if you're interested with your macro magic. No big deal if not.


Discussion / hints:

I'll take a look!
Whoops, forgot to leave a second comment! I have it pretty much all figured out, as I stripped out the bit mentioned in the original issue.

I believe I found a bug in quickcheck, but have yet to file an issue on it. Other than that I think everything works.

Thank you, though!
Oh, okay. :slightly_smiling_face: In that case I'd gladly review the changes instead, if you want. Let me know if you need anything!
Ok! I'll let you know when a PR goes up if you'd like.

Fix patch:
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 016fb5deb..830ba1a3b 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -20,7 +20,7 @@ jobs:
     runs-on: ubuntu-20.04
     strategy:
       matrix:
-        rust: ["1.40", stable]
+        rust: ["1.46", stable]
         target:
           - { name: NetBSD, triple: x86_64-unknown-netbsd, has_std: true }
           - { name: Solaris, triple: x86_64-sun-solaris, has_std: true }
@@ -121,7 +121,7 @@ jobs:
     runs-on: ${{ matrix.os.value }}
     strategy:
       matrix:
-        rust: ["1.40", stable]
+        rust: ["1.46", stable]
         os:
           - { name: Ubuntu, value: ubuntu-20.04 }
           - { name: Windows, value: windows-latest }
diff --git a/.github/workflows/scheduled.yaml b/.github/workflows/scheduled.yaml
index 3b2db70cd..2baa8d27d 100644
--- a/.github/workflows/scheduled.yaml
+++ b/.github/workflows/scheduled.yaml
@@ -55,8 +55,7 @@ jobs:
           - { name: "ARM64 Fuchsia", triple: aarch64-fuchsia, has_std: true }
           - { name: "ARM64 Android", triple: aarch64-linux-android, has_std: true }
           - { name: "Bare Cortex", triple: thumbv7em-none-eabihf, has_std: false }
-          - { name: "WebAssembly", triple: wasm32-unknown-unknown, has_std: true }
-          - { name: "WebAssembly with WASI", triple: wasm32-wasi, has_std: true }
+          - { name: "WASI", triple: wasm32-wasi, has_std: true }
           - { name: "64-bit Fuchsia", triple: x86_64-fuchsia, has_std: true }
           - { name: "64-bit x86 Android", triple: x86_64-linux-android, has_std: true }
           - { name: "64-bit Solaris", triple: x86_64-sun-solaris, has_std: true }
@@ -86,7 +85,7 @@ jobs:
           args: |
             check
             --no-dev-deps
-            --version-range 1.40..
+            --version-range 1.46..
             --feature-powerset
             --optional-deps
             --exclude-features default,winapi,std,local-offset,time-macros,quickcheck,quickcheck-dep
@@ -101,7 +100,7 @@ jobs:
           args: |
             check
             --no-dev-deps
-            --version-range 1.40..
+            --version-range 1.46..
             --feature-powerset
             --optional-deps
             --exclude-features default,winapi,time-macros,quickcheck-dep
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0085698a0..9b0361d87 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -48,7 +48,9 @@ Versioning].
 
 ### Changed
 
-- The minimum supported Rust version is now 1.40.0.
+- The minimum supported Rust version is now 1.46.0.
+- rand has been updated to 0.8.
+- quickcheck has been updated to 1.0.
 - Macros are placed behind the `macros` feature flag.
 - All macros now accept strings, rather than unquoted tokens. The syntax
   accepted is otherwise the same as before.
@@ -103,13 +105,6 @@ Versioning].
   - `OffsetDateTime::nanosecond`
   - `OffsetDateTime::unix_timestamp`
   - `OffsetDateTime::unix_timestamp_nanos`
-- No longer `const fn` on older compilers
-  - `util::is_leap_year`
-  - `util::days_in_year`
-  - `Duration::new`
-  - `Duration::is_positive`
-  - `Duration::is_negative`
-  - `Duration::is_zero`
 - Some variants of `Error` no longer contain an inner item. This is because the
   item is already guaranteed to be a zero-sized struct.
 - The following functions now return a `Result`:
diff --git a/Cargo.toml b/Cargo.toml
index ff0ac5454..fe7e660f3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,29 +21,29 @@ rustdoc-args = ["--cfg", "__time_03_docs"]
 default = ["std", "const_fn"]
 macros = ["time-macros"]
 local-offset = ["std", "winapi"]
-quickcheck = ["quickcheck-dep", "rand", "std"]
+quickcheck = ["quickcheck-dep", "alloc"]
 std = ["alloc"]
 alloc = []
-large-dates = ["time-macros/large-dates"]
+large-dates = ["time-macros/large-dates"] # Weak feature dependencies would be nice here! See rust-lang/cargo#8832 for status.
 
 [dependencies]
-const_fn = { version = "0.4.4", optional = true }
+const_fn = { version = "0.4.5", optional = true }
 itoa = { version = "0.4.7", default-features = false } # TODO make optional when formatting is made optional
-quickcheck-dep = { package = "quickcheck", version = "0.9.2", optional = true }
-rand = { version = "0.7.3", optional = true, default-features = false }
-serde = { version = "1.0.117", optional = true, default-features = false, features = ["derive"] }
+quickcheck-dep = { package = "quickcheck", version = "1.0.3", optional = true }
+rand = { version = "0.8.2", optional = true, default-features = false }
+serde = { version = "1.0.119", optional = true, default-features = false, features = ["derive"] }
 time-macros = { version = "=0.2.0-dev", path = "time-macros", optional = true }
 
 [workspace]
-members = ["time-benchmarks", "time-macros", "time-macros-impl"]
+members = ["time-benchmarks", "time-macros"]
 
 [target.'cfg(windows)'.dependencies]
 winapi = { version = "0.3.9", features = ["minwinbase", "minwindef", "timezoneapi"], optional = true }
 
 [target.'cfg(unsound_local_offset)'.dependencies]
-libc = "0.2.81"
+libc = "0.2.82"
 
 [dev-dependencies]
-rand = { version = "0.7.3", default-features = false }
-serde_json = "1.0.59"
+rand = { version = "0.8.2", default-features = false }
+serde_json = "1.0.61"
 time-macros = { path = "time-macros" }
diff --git a/README.md b/README.md
index 516374618..389af064a 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 [![GitHub time-rs/time](https://img.shields.io/badge/GitHub-time--rs%2Ftime-9b88bb?logo=github&style=for-the-badge)](https://github.com/time-rs/time)
 ![license MIT or Apache-2.0](https://img.shields.io/badge/license-MIT%20or%20Apache--2.0-779a6b?style=for-the-badge)
-[![minimum rustc 1.40.0](https://img.shields.io/badge/minimum%20rustc-1.40.0-c18170?logo=rust&style=for-the-badge)](https://www.whatrustisit.com)
+[![minimum rustc 1.46](https://img.shields.io/badge/minimum%20rustc-1.46-c18170?logo=rust&style=for-the-badge)](https://www.whatrustisit.com)
 [![version](https://img.shields.io/crates/v/time?color=97935d&logo=rust&style=for-the-badge)](https://crates.io/crates/time)
 [![build status](https://img.shields.io/endpoint?url=https://runkit.io/jhpratt/time-rs-status-badge/branches/master)](https://github.com/time-rs/time/actions)
 
diff --git a/src/date.rs b/src/date.rs
index 69e1c65fe..47b350aa0 100644
--- a/src/date.rs
+++ b/src/date.rs
@@ -77,12 +77,7 @@ impl Date {
     /// # use time::Date;
     /// assert!(Date::from_calendar_date(2019, 2, 29).is_err()); // 2019 isn't a leap year.
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn from_calendar_date(
+    pub const fn from_calendar_date(
         year: i32,
         month: u8,
         day: u8,
@@ -116,12 +111,7 @@ impl Date {
     /// # use time::Date;
     /// assert!(Date::from_ordinal_date(2019, 366).is_err()); // 2019 isn't a leap year.
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn from_ordinal_date(year: i32, ordinal: u16) -> Result<Self, error::ComponentRange> {
+    pub const fn from_ordinal_date(year: i32, ordinal: u16) -> Result<Self, error::ComponentRange> {
         ensure_value_in_range!(year in MIN_YEAR => MAX_YEAR);
         ensure_value_in_range!(ordinal conditionally in 1 => days_in_year(year));
         Ok(Self::from_ordinal_date_unchecked(year, ordinal))
@@ -140,12 +130,7 @@ impl Date {
     /// # use time::{Date, Weekday::*};
     /// assert!(Date::from_iso_week_date(2019, 53, Monday).is_err()); // 2019 doesn't have 53 weeks.
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn from_iso_week_date(
+    pub const fn from_iso_week_date(
         year: i32,
         week: u8,
         weekday: Weekday,
@@ -203,12 +188,7 @@ impl Date {
     /// assert_eq!(date!("2019-01-01").month(), 1);
     /// assert_eq!(date!("2019-12-31").month(), 12);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn month(self) -> u8 {
+    pub const fn month(self) -> u8 {
         self.month_day().0
     }
 
@@ -222,20 +202,14 @@ impl Date {
     /// assert_eq!(date!("2019-01-01").day(), 1);
     /// assert_eq!(date!("2019-12-31").day(), 31);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn day(self) -> u8 {
+    pub const fn day(self) -> u8 {
         self.month_day().1
     }
 
     /// Get the month and day. This is more efficient than fetching the components individually.
     // For whatever reason, rustc has difficulty optimizing this function. It's significantly faster
     // to write the statements out by hand.
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub(crate) fn month_day(self) -> (u8, u8) {
+    pub(crate) const fn month_day(self) -> (u8, u8) {
         /// The number of days up to and including the given month. Common years
         /// are first, followed by leap years.
         const CUMULATIVE_DAYS_IN_MONTH_COMMON_LEAP: [[u16; 11]; 2] = [
@@ -287,8 +261,7 @@ impl Date {
     }
 
     /// Get the ISO 8601 year and week number.
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub(crate) fn iso_year_week(self) -> (i32, u8) {
+    pub(crate) const fn iso_year_week(self) -> (i32, u8) {
         let (year, ordinal) = self.to_ordinal_date();
 
         match ((ordinal + 10 - self.weekday().iso_weekday_number() as u16) / 7) as _ {
@@ -310,12 +283,7 @@ impl Date {
     /// assert_eq!(date!("2020-12-31").iso_week(), 53);
     /// assert_eq!(date!("2021-01-01").iso_week(), 53);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn iso_week(self) -> u8 {
+    pub const fn iso_week(self) -> u8 {
         self.iso_year_week().1
     }
 
@@ -330,12 +298,7 @@ impl Date {
     /// assert_eq!(date!("2020-12-31").sunday_based_week(), 52);
     /// assert_eq!(date!("2021-01-01").sunday_based_week(), 0);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn sunday_based_week(self) -> u8 {
+    pub const fn sunday_based_week(self) -> u8 {
         ((self.ordinal() as i16 - self.weekday().number_days_from_sunday() as i16 + 6) / 7) as _
     }
 
@@ -350,12 +313,7 @@ impl Date {
     /// assert_eq!(date!("2020-12-31").monday_based_week(), 52);
     /// assert_eq!(date!("2021-01-01").monday_based_week(), 0);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn monday_based_week(self) -> u8 {
+    pub const fn monday_based_week(self) -> u8 {
         ((self.ordinal() as i16 - self.weekday().number_days_from_monday() as i16 + 6) / 7) as _
     }
 
@@ -365,12 +323,7 @@ impl Date {
     /// # use time_macros::date;
     /// assert_eq!(date!("2019-01-01").to_calendar_date(), (2019, 1, 1));
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_calendar_date(self) -> (i32, u8, u8) {
+    pub const fn to_calendar_date(self) -> (i32, u8, u8) {
         let (month, day) = self.month_day();
         (self.year(), month, day)
     }
@@ -396,12 +349,7 @@ impl Date {
     /// assert_eq!(date!("2020-12-31").to_iso_week_date(), (2020, 53, Thursday));
     /// assert_eq!(date!("2021-01-01").to_iso_week_date(), (2020, 53, Friday));
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_iso_week_date(self) -> (i32, u8, Weekday) {
+    pub const fn to_iso_week_date(self) -> (i32, u8, Weekday) {
         let (year, ordinal) = self.to_ordinal_date();
         let weekday = self.weekday();
 
@@ -430,12 +378,7 @@ impl Date {
     /// assert_eq!(date!("2019-11-01").weekday(), Friday);
     /// assert_eq!(date!("2019-12-01").weekday(), Sunday);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn weekday(self) -> Weekday {
+    pub const fn weekday(self) -> Weekday {
         match self.to_julian_day() % 7 {
             -6 | 1 => Weekday::Tuesday,
             -5 | 2 => Weekday::Wednesday,
@@ -509,16 +452,10 @@ impl Date {
     /// assert_eq!(date!("2019-01-01").to_julian_day(), 2_458_485);
     /// assert_eq!(date!("2019-12-31").to_julian_day(), 2_458_849);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_julian_day(self) -> i32 {
+    pub const fn to_julian_day(self) -> i32 {
         /// Floored division for integers. This differs from the default behavior, which is
         /// truncation.
-        #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-        pub(crate) fn div_floor(a: i32, b: i32) -> i32 {
+        pub(crate) const fn div_floor(a: i32, b: i32) -> i32 {
             let (quotient, remainder) = (a / b, a % b);
 
             if (remainder > 0 && b < 0) || (remainder < 0 && b > 0) {
@@ -549,13 +486,8 @@ impl Date {
     /// assert_eq!(Date::from_julian_day(2_458_485), Ok(date!("2019-01-01")));
     /// assert_eq!(Date::from_julian_day(2_458_849), Ok(date!("2019-12-31")));
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
     #[cfg_attr(__time_03_docs, doc(alias = "from_julian_date"))]
-    pub fn from_julian_day(julian_day: i32) -> Result<Self, error::ComponentRange> {
+    pub const fn from_julian_day(julian_day: i32) -> Result<Self, error::ComponentRange> {
         #![allow(trivial_numeric_casts)] // cast depends on type alias
 
         /// A type that is either `i32` or `i64`. This subtle difference allows for optimization
@@ -568,8 +500,7 @@ impl Date {
 
         /// Floored division for integers. This differs from the default
         /// behavior, which is truncation.
-        #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-        pub(crate) fn div_floor(a: MaybeWidened, b: i32) -> i32 {
+        pub(crate) const fn div_floor(a: MaybeWidened, b: i32) -> i32 {
             let (quotient, remainder) = (a / b as MaybeWidened, a % b as MaybeWidened);
 
             if (remainder > 0 && b < 0) || (remainder < 0 && b > 0) {
@@ -650,12 +581,7 @@ impl Date {
     /// assert!(date!("1970-01-01").with_hms(0, 0, 0).is_ok());
     /// assert!(date!("1970-01-01").with_hms(24, 0, 0).is_err());
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn with_hms(
+    pub const fn with_hms(
         self,
         hour: u8,
         minute: u8,
@@ -674,12 +600,7 @@ impl Date {
     /// assert!(date!("1970-01-01").with_hms_milli(0, 0, 0, 0).is_ok());
     /// assert!(date!("1970-01-01").with_hms_milli(24, 0, 0, 0).is_err());
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn with_hms_milli(
+    pub const fn with_hms_milli(
         self,
         hour: u8,
         minute: u8,
@@ -699,12 +620,7 @@ impl Date {
     /// assert!(date!("1970-01-01").with_hms_micro(0, 0, 0, 0).is_ok());
     /// assert!(date!("1970-01-01").with_hms_micro(24, 0, 0, 0).is_err());
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn with_hms_micro(
+    pub const fn with_hms_micro(
         self,
         hour: u8,
         minute: u8,
@@ -724,12 +640,7 @@ impl Date {
     /// assert!(date!("1970-01-01").with_hms_nano(0, 0, 0, 0).is_ok());
     /// assert!(date!("1970-01-01").with_hms_nano(24, 0, 0, 0).is_err());
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn with_hms_nano(
+    pub const fn with_hms_nano(
         self,
         hour: u8,
         minute: u8,
diff --git a/src/duration.rs b/src/duration.rs
index c820b14b8..0b17d8532 100644
--- a/src/duration.rs
+++ b/src/duration.rs
@@ -144,12 +144,7 @@ impl Duration {
     /// assert!(0.seconds().is_zero());
     /// assert!(!1.nanoseconds().is_zero());
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn is_zero(self) -> bool {
+    pub const fn is_zero(self) -> bool {
         self.seconds == 0 && self.nanoseconds == 0
     }
 
@@ -161,12 +156,7 @@ impl Duration {
     /// assert!(!0.seconds().is_negative());
     /// assert!(!1.seconds().is_negative());
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn is_negative(self) -> bool {
+    pub const fn is_negative(self) -> bool {
         self.seconds < 0 || self.nanoseconds < 0
     }
 
@@ -178,12 +168,7 @@ impl Duration {
     /// assert!(!0.seconds().is_positive());
     /// assert!(!(-1).seconds().is_positive());
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn is_positive(self) -> bool {
+    pub const fn is_positive(self) -> bool {
         self.seconds > 0 || self.nanoseconds > 0
     }
 
@@ -220,12 +205,7 @@ impl Duration {
     /// assert_eq!(Duration::new(-1, 0), (-1).seconds());
     /// assert_eq!(Duration::new(1, 2_000_000_000), 3.seconds());
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn new(mut seconds: i64, mut nanoseconds: i32) -> Self {
+    pub const fn new(mut seconds: i64, mut nanoseconds: i32) -> Self {
         seconds += nanoseconds as i64 / 1_000_000_000;
         nanoseconds %= 1_000_000_000;
 
@@ -636,12 +616,7 @@ impl Duration {
     /// assert_eq!(10.seconds().checked_div(-2), Some((-5).seconds()));
     /// assert_eq!(1.seconds().checked_div(0), None);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.47."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.47"))]
-    pub fn checked_div(self, rhs: i32) -> Option<Self> {
+    pub const fn checked_div(self, rhs: i32) -> Option<Self> {
         if rhs == 0 {
             return None;
         }
diff --git a/src/lib.rs b/src/lib.rs
index a84eb50b4..33bd640e3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -50,7 +50,7 @@
 //!
 //!   Enables [rand](https://docs.rs/rand) support for all types.
 //!
-//! - `quickcheck` (_implicitly enables `rand`_)
+//! - `quickcheck` (_implicitly enables `alloc`_)
 //!
 //!   Enables [quickcheck](https://docs.rs/quickcheck) support for all types except [`Instant`].
 //!
@@ -107,8 +107,7 @@
     clippy::map_err_ignore,
     clippy::missing_errors_doc,
     clippy::must_use_candidate,
-    clippy::redundant_pub_crate,
-    clippy::wildcard_imports
+    clippy::redundant_pub_crate
 )]
 #![doc(html_favicon_url = "https://avatars0.githubusercontent.com/u/55999857")]
 #![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/55999857")]
diff --git a/src/offset_date_time.rs b/src/offset_date_time.rs
index 58a423f75..78d87f142 100644
--- a/src/offset_date_time.rs
+++ b/src/offset_date_time.rs
@@ -144,12 +144,7 @@ impl OffsetDateTime {
     /// );
     /// # Ok::<_, time::Error>(())
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn from_unix_timestamp(timestamp: i64) -> Result<Self, error::ComponentRange> {
+    pub const fn from_unix_timestamp(timestamp: i64) -> Result<Self, error::ComponentRange> {
         let unix_epoch_julian_date = Date::from_ordinal_date_unchecked(1970, 1).to_julian_day();
 
         let date = const_try!(Date::from_julian_day(
@@ -193,12 +188,7 @@ impl OffsetDateTime {
     ///     Ok(datetime!("2019-01-01 0:00 UTC")),
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn from_unix_timestamp_nanos(timestamp: i128) -> Result<Self, error::ComponentRange> {
+    pub const fn from_unix_timestamp_nanos(timestamp: i128) -> Result<Self, error::ComponentRange> {
         let unix_epoch_julian_date = Date::from_ordinal_date_unchecked(1970, 1).to_julian_day();
 
         // Performing the division early lets us use an i64 instead of an i128.
@@ -254,12 +244,7 @@ impl OffsetDateTime {
     /// assert_eq!(datetime!("1970-01-01 0:00 UTC").unix_timestamp(), 0);
     /// assert_eq!(datetime!("1970-01-01 0:00 -1").unix_timestamp(), 3_600);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn unix_timestamp(self) -> i64 {
+    pub const fn unix_timestamp(self) -> i64 {
         let days = (self.utc_datetime.date.to_julian_day()
             - Date::from_ordinal_date_unchecked(1970, 1).to_julian_day())
             * 86_400;
@@ -279,12 +264,7 @@ impl OffsetDateTime {
     ///     3_600_000_000_000,
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn unix_timestamp_nanos(self) -> i128 {
+    pub const fn unix_timestamp_nanos(self) -> i128 {
         self.unix_timestamp() as i128 * 1_000_000_000 + self.utc_datetime.nanosecond() as i128
     }
 
@@ -300,12 +280,7 @@ impl OffsetDateTime {
     ///     date!("2018-12-31"),
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn date(self) -> Date {
+    pub const fn date(self) -> Date {
         let second = self.utc_datetime.second() as i8 + self.offset.seconds;
         let mut minute = self.utc_datetime.minute() as i8 + self.offset.minutes;
         let mut hour = self.utc_datetime.hour() as i8 + self.offset.hours;
@@ -349,12 +324,7 @@ impl OffsetDateTime {
     ///     time!("23:00")
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn time(self) -> Time {
+    pub const fn time(self) -> Time {
         let mut second = self.utc_datetime.second() as i8 + self.offset.seconds;
         let mut minute = self.utc_datetime.minute() as i8 + self.offset.minutes;
         let mut hour = self.utc_datetime.hour() as i8 + self.offset.hours;
@@ -401,12 +371,7 @@ impl OffsetDateTime {
     /// );
     /// assert_eq!(datetime!("2020-01-01 0:00 UTC").year(), 2020);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn year(self) -> i32 {
+    pub const fn year(self) -> i32 {
         let second = self.utc_datetime.second() as i8 + self.offset.seconds;
         let mut minute = self.utc_datetime.minute() as i8 + self.offset.minutes;
         let mut hour = self.utc_datetime.hour() as i8 + self.offset.hours;
@@ -450,12 +415,7 @@ impl OffsetDateTime {
     ///     1,
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn month(self) -> u8 {
+    pub const fn month(self) -> u8 {
         self.date().month()
     }
 
@@ -473,12 +433,7 @@ impl OffsetDateTime {
     ///     1,
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn day(self) -> u8 {
+    pub const fn day(self) -> u8 {
         self.date().day()
     }
 
@@ -496,12 +451,7 @@ impl OffsetDateTime {
     ///     1,
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn ordinal(self) -> u16 {
+    pub const fn ordinal(self) -> u16 {
         let second = self.utc_datetime.second() as i8 + self.offset.seconds;
         let mut minute = self.utc_datetime.minute() as i8 + self.offset.minutes;
         let mut hour = self.utc_datetime.hour() as i8 + self.offset.hours;
@@ -542,12 +492,7 @@ impl OffsetDateTime {
     /// assert_eq!(datetime!("2020-12-31 0:00 UTC").iso_week(), 53);
     /// assert_eq!(datetime!("2021-01-01 0:00 UTC").iso_week(), 53);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn iso_week(self) -> u8 {
+    pub const fn iso_week(self) -> u8 {
         self.date().iso_week()
     }
 
@@ -562,12 +507,7 @@ impl OffsetDateTime {
     /// assert_eq!(datetime!("2020-12-31 0:00 UTC").sunday_based_week(), 52);
     /// assert_eq!(datetime!("2021-01-01 0:00 UTC").sunday_based_week(), 0);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn sunday_based_week(self) -> u8 {
+    pub const fn sunday_based_week(self) -> u8 {
         self.date().sunday_based_week()
     }
 
@@ -582,12 +522,7 @@ impl OffsetDateTime {
     /// assert_eq!(datetime!("2020-12-31 0:00 UTC").monday_based_week(), 52);
     /// assert_eq!(datetime!("2021-01-01 0:00 UTC").monday_based_week(), 0);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn monday_based_week(self) -> u8 {
+    pub const fn monday_based_week(self) -> u8 {
         self.date().monday_based_week()
     }
 
@@ -600,12 +535,7 @@ impl OffsetDateTime {
     ///     (2019, 1, 1)
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_calendar_date(self) -> (i32, u8, u8) {
+    pub const fn to_calendar_date(self) -> (i32, u8, u8) {
         self.date().to_calendar_date()
     }
 
@@ -618,12 +548,7 @@ impl OffsetDateTime {
     ///     (2019, 1)
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_ordinal_date(self) -> (i32, u16) {
+    pub const fn to_ordinal_date(self) -> (i32, u16) {
         self.date().to_ordinal_date()
     }
 
@@ -653,12 +578,7 @@ impl OffsetDateTime {
     ///     (2020, 53, Friday)
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_iso_week_date(self) -> (i32, u8, Weekday) {
+    pub const fn to_iso_week_date(self) -> (i32, u8, Weekday) {
         self.date().to_iso_week_date()
     }
 
@@ -671,12 +591,7 @@ impl OffsetDateTime {
     /// assert_eq!(datetime!("2019-02-01 0:00 UTC").weekday(), Friday);
     /// assert_eq!(datetime!("2019-03-01 0:00 UTC").weekday(), Friday);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn weekday(self) -> Weekday {
+    pub const fn weekday(self) -> Weekday {
         self.date().weekday()
     }
 
@@ -692,12 +607,7 @@ impl OffsetDateTime {
     /// assert_eq!(datetime!("2019-01-01 0:00 UTC").to_julian_day(), 2_458_485);
     /// assert_eq!(datetime!("2019-12-31 0:00 UTC").to_julian_day(), 2_458_849);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_julian_day(self) -> i32 {
+    pub const fn to_julian_day(self) -> i32 {
         self.date().to_julian_day()
     }
 
@@ -708,12 +618,7 @@ impl OffsetDateTime {
     /// assert_eq!(datetime!("2020-01-01 0:00:00 UTC").to_hms(), (0, 0, 0));
     /// assert_eq!(datetime!("2020-01-01 23:59:59 UTC").to_hms(), (23, 59, 59));
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_hms(self) -> (u8, u8, u8) {
+    pub const fn to_hms(self) -> (u8, u8, u8) {
         self.time().as_hms()
     }
 
@@ -730,12 +635,7 @@ impl OffsetDateTime {
     ///     (23, 59, 59, 999)
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_hms_milli(self) -> (u8, u8, u8, u16) {
+    pub const fn to_hms_milli(self) -> (u8, u8, u8, u16) {
         self.time().as_hms_milli()
     }
 
@@ -752,12 +652,7 @@ impl OffsetDateTime {
     ///     (23, 59, 59, 999_999)
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_hms_micro(self) -> (u8, u8, u8, u32) {
+    pub const fn to_hms_micro(self) -> (u8, u8, u8, u32) {
         self.time().as_hms_micro()
     }
 
@@ -774,12 +669,7 @@ impl OffsetDateTime {
     ///     (23, 59, 59, 999_999_999)
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_hms_nano(self) -> (u8, u8, u8, u32) {
+    pub const fn to_hms_nano(self) -> (u8, u8, u8, u32) {
         self.time().as_hms_nano()
     }
 
@@ -797,12 +687,7 @@ impl OffsetDateTime {
     ///     21,
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn hour(self) -> u8 {
+    pub const fn hour(self) -> u8 {
         let second = self.utc_datetime.second() as i8 + self.offset.seconds;
         let mut minute = self.utc_datetime.minute() as i8 + self.offset.minutes;
         let mut hour = self.utc_datetime.hour() as i8 + self.offset.hours;
@@ -840,12 +725,7 @@ impl OffsetDateTime {
     ///     29,
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn minute(self) -> u8 {
+    pub const fn minute(self) -> u8 {
         let second = self.utc_datetime.second() as i8 + self.offset.seconds;
         let mut minute = self.utc_datetime.minute() as i8 + self.offset.minutes;
 
@@ -877,12 +757,7 @@ impl OffsetDateTime {
     ///     29,
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn second(self) -> u8 {
+    pub const fn second(self) -> u8 {
         let mut second = self.utc_datetime.second() as i8 + self.offset.seconds;
 
         if second >= 60 {
@@ -963,13 +838,8 @@ impl OffsetDateTime {
     ///     datetime!("2020-01-01 12:00 +1")
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
     #[must_use = "This method does not mutate the original `OffsetDateTime`."]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn replace_time(self, time: Time) -> Self {
+    pub const fn replace_time(self, time: Time) -> Self {
         self.utc_datetime
             .utc_to_offset(self.offset)
             .replace_time(time)
@@ -990,13 +860,8 @@ impl OffsetDateTime {
     ///     datetime!("2020-01-30 0:00 +1")
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
     #[must_use = "This method does not mutate the original `OffsetDateTime`."]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn replace_date(self, date: Date) -> Self {
+    pub const fn replace_date(self, date: Date) -> Self {
         self.utc_datetime
             .utc_to_offset(self.offset)
             .replace_date(date)
@@ -1017,13 +882,8 @@ impl OffsetDateTime {
     ///     datetime!("2020-01-30 0:00 +1")
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
     #[must_use = "This method does not mutate the original `OffsetDateTime`."]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn replace_date_time(self, date_time: PrimitiveDateTime) -> Self {
+    pub const fn replace_date_time(self, date_time: PrimitiveDateTime) -> Self {
         date_time.assume_offset(self.offset)
     }
 
@@ -1036,13 +896,8 @@ impl OffsetDateTime {
     ///     datetime!("2020-01-01 0:00 -5")
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
     #[must_use = "This method does not mutate the original `OffsetDateTime`."]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn replace_offset(self, offset: UtcOffset) -> Self {
+    pub const fn replace_offset(self, offset: UtcOffset) -> Self {
         self.utc_datetime.assume_offset(offset)
     }
 }
diff --git a/src/primitive_date_time.rs b/src/primitive_date_time.rs
index a210a872d..f9f4f0351 100644
--- a/src/primitive_date_time.rs
+++ b/src/primitive_date_time.rs
@@ -82,12 +82,7 @@ impl PrimitiveDateTime {
     /// assert_eq!(datetime!("2019-01-01 0:00").month(), 1);
     /// assert_eq!(datetime!("2019-12-31 0:00").month(), 12);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn month(self) -> u8 {
+    pub const fn month(self) -> u8 {
         self.date.month()
     }
 
@@ -100,12 +95,7 @@ impl PrimitiveDateTime {
     /// assert_eq!(datetime!("2019-01-01 0:00").day(), 1);
     /// assert_eq!(datetime!("2019-12-31 0:00").day(), 31);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn day(self) -> u8 {
+    pub const fn day(self) -> u8 {
         self.date.day()
     }
 
@@ -134,12 +124,7 @@ impl PrimitiveDateTime {
     /// assert_eq!(datetime!("2020-12-31 0:00").iso_week(), 53);
     /// assert_eq!(datetime!("2021-01-01 0:00").iso_week(), 53);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn iso_week(self) -> u8 {
+    pub const fn iso_week(self) -> u8 {
         self.date.iso_week()
     }
 
@@ -154,12 +139,7 @@ impl PrimitiveDateTime {
     /// assert_eq!(datetime!("2020-12-31 0:00").sunday_based_week(), 52);
     /// assert_eq!(datetime!("2021-01-01 0:00").sunday_based_week(), 0);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn sunday_based_week(self) -> u8 {
+    pub const fn sunday_based_week(self) -> u8 {
         self.date.sunday_based_week()
     }
 
@@ -174,12 +154,7 @@ impl PrimitiveDateTime {
     /// assert_eq!(datetime!("2020-12-31 0:00").monday_based_week(), 52);
     /// assert_eq!(datetime!("2021-01-01 0:00").monday_based_week(), 0);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn monday_based_week(self) -> u8 {
+    pub const fn monday_based_week(self) -> u8 {
         self.date.monday_based_week()
     }
 
@@ -192,12 +167,7 @@ impl PrimitiveDateTime {
     ///     (2019, 1, 1)
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_calendar_date(self) -> (i32, u8, u8) {
+    pub const fn to_calendar_date(self) -> (i32, u8, u8) {
         self.date.to_calendar_date()
     }
 
@@ -237,12 +207,7 @@ impl PrimitiveDateTime {
     ///     (2020, 53, Friday)
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_iso_week_date(self) -> (i32, u8, Weekday) {
+    pub const fn to_iso_week_date(self) -> (i32, u8, Weekday) {
         self.date.to_iso_week_date()
     }
 
@@ -264,12 +229,7 @@ impl PrimitiveDateTime {
     /// assert_eq!(datetime!("2019-11-01 0:00").weekday(), Friday);
     /// assert_eq!(datetime!("2019-12-01 0:00").weekday(), Sunday);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn weekday(self) -> Weekday {
+    pub const fn weekday(self) -> Weekday {
         self.date.weekday()
     }
 
@@ -285,12 +245,7 @@ impl PrimitiveDateTime {
     /// assert_eq!(datetime!("2019-01-01 0:00").to_julian_day(), 2_458_485);
     /// assert_eq!(datetime!("2019-12-31 0:00").to_julian_day(), 2_458_849);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn to_julian_day(self) -> i32 {
+    pub const fn to_julian_day(self) -> i32 {
         self.date.to_julian_day()
     }
 
@@ -449,12 +404,7 @@ impl PrimitiveDateTime {
     ///     1_546_304_400,
     /// );
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn assume_offset(self, offset: UtcOffset) -> OffsetDateTime {
+    pub const fn assume_offset(self, offset: UtcOffset) -> OffsetDateTime {
         OffsetDateTime {
             utc_datetime: self.offset_to_utc(offset),
             offset,
@@ -514,8 +464,7 @@ impl PrimitiveDateTime {
 impl PrimitiveDateTime {
     /// Assuming that the current [`PrimitiveDateTime`] is a value in the provided [`UtcOffset`],
     /// obtain the equivalent value in the UTC.
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub(crate) fn offset_to_utc(self, offset: UtcOffset) -> Self {
+    pub(crate) const fn offset_to_utc(self, offset: UtcOffset) -> Self {
         let mut second = self.second() as i8 - offset.seconds;
         let mut minute = self.minute() as i8 - offset.minutes;
         let mut hour = self.hour() as i8 - offset.hours;
@@ -564,8 +513,7 @@ impl PrimitiveDateTime {
 
     /// Assuming that the current [`PrimitiveDateTime`] is a value in UTC, obtain the equivalent
     /// value in the provided [`UtcOffset`].
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub(crate) fn utc_to_offset(self, offset: UtcOffset) -> Self {
+    pub(crate) const fn utc_to_offset(self, offset: UtcOffset) -> Self {
         self.offset_to_utc(UtcOffset {
             hours: -offset.hours,
             minutes: -offset.minutes,
diff --git a/src/quickcheck.rs b/src/quickcheck.rs
index c3487759a..a3eb35fb8 100644
--- a/src/quickcheck.rs
+++ b/src/quickcheck.rs
@@ -42,238 +42,202 @@ use crate::{
     util::days_in_year,
     Date, Duration, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset, Weekday,
 };
-use core::{cmp, convert::TryInto, i32, iter, u16, u32, u8};
-use quickcheck_dep::{Arbitrary, Gen};
-use rand::Rng;
-
-/// Shim for the unstable clamp method.
-// This method seems likely to stabilized in Rust 1.50. This will result in a NET usage date of
-// 2021-08-11.
-trait Clamp {
-    /// Constrain `self` between `min` and `max` (inclusive).
-    ///
-    /// If `self` is less than `min`, returns `min`.
-    /// If `self` is greater than `max`, returns `max`.
-    /// Otherwise, returns `self`.
-    fn clamp_(self, min: Self, max: Self) -> Self;
-}
-
-impl<T: Ord> Clamp for T {
-    fn clamp_(self, min: Self, max: Self) -> Self {
-        core::cmp::max(min, core::cmp::min(self, max))
+use alloc::boxed::Box;
+use quickcheck_dep::{empty_shrinker, single_shrinker, Arbitrary, Gen};
+
+/// Obtain an arbitrary value between the minimum and maximum inclusive.
+fn arbitrary_between<T>(g: &mut Gen, min: T, max: T) -> T
+where
+    T: PartialOrd
+        + core::ops::AddAssign
+        + core::ops::Add<Output = T>
+        + core::ops::Sub<Output = T>
+        + core::ops::Rem<Output = T>
+        + Arbitrary
+        + Copy,
+{
+    #[allow(clippy::eq_op)]
+    let zero = min - min;
+
+    let range = max - min;
+    let mut within_range = T::arbitrary(g) % range;
+
+    if within_range < zero {
+        within_range += range;
     }
+
+    within_range + min
 }
 
 #[cfg_attr(__time_03_docs, doc(cfg(feature = "quickcheck")))]
 impl Arbitrary for Date {
-    fn arbitrary<G: Gen>(g: &mut G) -> Self {
-        let year_size = g.size().try_into().unwrap_or(i32::MAX);
-        let year = if year_size == 0 {
-            0
-        } else {
-            g.gen_range(
-                cmp::max(MIN_YEAR, -year_size),
-                cmp::min(MAX_YEAR, year_size),
-            )
-        };
-
-        let ordinal_size = cmp::min(g.size().try_into().unwrap_or(u16::MAX), days_in_year(year));
-        let ordinal = g.gen_range(1, cmp::max(2, ordinal_size + 1));
-
+    fn arbitrary(g: &mut Gen) -> Self {
+        let year = arbitrary_between(g, MIN_YEAR, MAX_YEAR);
+        let ordinal = arbitrary_between(g, 1, days_in_year(year));
         Self::from_ordinal_date_unchecked(year, ordinal)
     }
 
     fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
-        let (year, ordinal) = self.to_ordinal_date();
-
-        let shrunk_year = year
-            .shrink()
-            .flat_map(move |year| Self::from_ordinal_date(year, ordinal));
-        let shrunk_ordinal = ordinal
-            .shrink()
-            .flat_map(move |ordinal| Self::from_ordinal_date(year, ordinal));
-
-        Box::new(shrunk_year.chain(shrunk_ordinal))
+        Box::new(
+            self.to_ordinal_date()
+                .shrink()
+                .flat_map(|(year, ordinal)| Self::from_ordinal_date(year, ordinal)),
+        )
     }
 }
 
 #[cfg_attr(__time_03_docs, doc(cfg(feature = "quickcheck")))]
 impl Arbitrary for Duration {
-    fn arbitrary<G: Gen>(g: &mut G) -> Self {
+    fn arbitrary(g: &mut Gen) -> Self {
         let seconds = i64::arbitrary(g);
-        let nanoseconds: i32 = g.gen_range(
-            0,
-            g.size()
-                .try_into()
-                .unwrap_or(i32::MAX)
-                .clamp_(1, 1_000_000_000),
-        );
+        let mut nanoseconds = arbitrary_between(g, 0, 999_999_999);
+
+        // Coerce the sign if necessary. Also allow for the creation of a negative Duration under
+        // one second.
+        if seconds < 0 || (seconds == 0 && bool::arbitrary(g)) {
+            nanoseconds *= -1;
+        }
+
         Self {
             seconds,
-            nanoseconds: nanoseconds * (seconds.signum() as i32),
+            nanoseconds,
         }
     }
 
     fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
-        let seconds = self.seconds;
-        let nanoseconds = self.nanoseconds;
-
-        let shrunk_seconds = seconds.shrink().map(move |seconds| Self {
-            seconds,
-            nanoseconds,
-        });
-        let shrunk_nanoseconds = nanoseconds.shrink().map(move |nanoseconds| Self {
-            seconds,
-            nanoseconds,
-        });
-
-        Box::new(shrunk_seconds.chain(shrunk_nanoseconds))
+        Box::new(
+            (self.nanoseconds, self.seconds)
+                .shrink()
+                .map(|(mut nanoseconds, seconds)| {
+                    // Coerce the sign if necessary.
+                    if (seconds > 0 && nanoseconds < 0) || (seconds < 0 && nanoseconds > 0) {
+                        nanoseconds *= -1;
+                    }
+
+                    Self {
+                        seconds,
+                        nanoseconds,
+                    }
+                }),
+        )
     }
 }
 
 #[cfg_attr(__time_03_docs, doc(cfg(feature = "quickcheck")))]
 impl Arbitrary for Time {
-    fn arbitrary<G: Gen>(g: &mut G) -> Self {
-        let hour = g.gen_range(0, g.size().try_into().unwrap_or(u8::MAX).clamp_(1, 24));
-        let minute = g.gen_range(0, g.size().try_into().unwrap_or(u8::MAX).clamp_(1, 60));
-        let second = g.gen_range(0, g.size().try_into().unwrap_or(u8::MAX).clamp_(1, 60));
-        let nanosecond = g.gen_range(
-            0,
-            g.size()
-                .try_into()
-                .unwrap_or(u32::MAX)
-                .clamp_(1, 1_000_000_000),
-        );
+    fn arbitrary(g: &mut Gen) -> Self {
         Self {
-            hour,
-            minute,
-            second,
-            nanosecond,
+            hour: arbitrary_between(g, 0, 23),
+            minute: arbitrary_between(g, 0, 59),
+            second: arbitrary_between(g, 0, 59),
+            nanosecond: arbitrary_between(g, 0, 999_999_999),
             padding: hack::Padding::Optimize,
         }
     }
 
     fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
-        let hour = self.hour;
-        let minute = self.minute;
-        let second = self.second;
-        let nanosecond = self.nanosecond;
-
-        let shrunk_hour = self.hour.shrink().map(move |hour| Self {
-            hour,
-            minute,
-            second,
-            nanosecond,
-            padding: hack::Padding::Optimize,
-        });
-        let shrunk_minute = minute.shrink().map(move |minute| Self {
-            hour,
-            minute,
-            second,
-            nanosecond,
-            padding: hack::Padding::Optimize,
-        });
-        let shrunk_second = second.shrink().map(move |second| Self {
-            hour,
-            minute,
-            second,
-            nanosecond,
-            padding: hack::Padding::Optimize,
-        });
-        let shrunk_nanos = nanosecond.shrink().map(move |nanosecond| Self {
-            hour,
-            minute,
-            second,
-            nanosecond,
-            padding: hack::Padding::Optimize,
-        });
-
         Box::new(
-            shrunk_hour
-                .chain(shrunk_minute)
-                .chain(shrunk_second)
-                .chain(shrunk_nanos),
+            self.as_hms_nano()
+                .shrink()
+                .map(|(hour, minute, second, nanosecond)| Self {
+                    hour,
+                    minute,
+                    second,
+                    nanosecond,
+                    padding: hack::Padding::Optimize,
+                }),
         )
     }
 }
 
 #[cfg_attr(__time_03_docs, doc(cfg(feature = "quickcheck")))]
 impl Arbitrary for PrimitiveDateTime {
-    fn arbitrary<G: Gen>(g: &mut G) -> Self {
+    fn arbitrary(g: &mut Gen) -> Self {
         Self::new(Date::arbitrary(g), Time::arbitrary(g))
     }
 
     fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
-        let date = self.date;
-        let time = self.time;
-
-        let shrunk_date = date.shrink().map(move |date| Self::new(date, time));
-        let shrunk_time = time.shrink().map(move |time| Self::new(date, time));
-
-        Box::new(shrunk_date.chain(shrunk_time))
+        Box::new(
+            (self.date, self.time)
+                .shrink()
+                .map(|(date, time)| Self { date, time }),
+        )
     }
 }
 
 #[cfg_attr(__time_03_docs, doc(cfg(feature = "quickcheck")))]
 impl Arbitrary for UtcOffset {
-    fn arbitrary<G: Gen>(g: &mut G) -> Self {
-        let total_seconds =
-            g.gen_range(0, g.size().try_into().unwrap_or(i32::MAX).clamp_(1, 86_400));
-
-        let mut hours = total_seconds / 3_600;
-        let mut minutes = (total_seconds / 60) % 60;
-        let mut seconds = total_seconds % 60;
-
-        if g.gen() {
-            hours *= -1;
+    fn arbitrary(g: &mut Gen) -> Self {
+        let hours = arbitrary_between(g, -23, 23);
+        let mut minutes = arbitrary_between(g, 0, 59);
+        let mut seconds = arbitrary_between(g, 0, 59);
+
+        // Coerce the signs if necessary. Also allow for the creation of a negative offset under one
+        // hour.
+        if hours < 0
+            || (hours == 0 && bool::arbitrary(g))
+            || (hours == 0 && minutes == 0 && bool::arbitrary(g))
+        {
             minutes *= -1;
             seconds *= -1;
         }
 
         Self {
-            hours: hours as _,
-            minutes: minutes as _,
-            seconds: seconds as _,
+            hours,
+            minutes,
+            seconds,
         }
     }
 
     fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
-        Box::new(self.to_seconds().shrink().map(move |total_seconds| Self {
-            hours: (total_seconds / 3_600) as _,
-            minutes: ((total_seconds / 60) % 60) as _,
-            seconds: (total_seconds % 60) as _,
-        }))
+        Box::new(
+            self.as_hms()
+                .shrink()
+                .map(|(hours, mut minutes, mut seconds)| {
+                    // Coerce the signs if necessary.
+                    if (hours > 0 && minutes < 0) || (hours < 0 && minutes > 0) {
+                        minutes *= -1;
+                    }
+                    if (hours > 0 && seconds < 0)
+                        || (hours < 0 && seconds > 0)
+                        || (minutes > 0 && seconds < 0)
+                        || (minutes < 0 && seconds > 0)
+                    {
+                        seconds *= -1;
+                    }
+
+                    Self {
+                        hours,
+                        minutes,
+                        seconds,
+                    }
+                }),
+        )
     }
 }
 
 #[cfg_attr(__time_03_docs, doc(cfg(feature = "quickcheck")))]
 impl Arbitrary for OffsetDateTime {
-    fn arbitrary<G: Gen>(g: &mut G) -> Self {
+    fn arbitrary(g: &mut Gen) -> Self {
         let datetime = PrimitiveDateTime::arbitrary(g);
         let offset = UtcOffset::arbitrary(g);
         datetime.assume_offset(offset)
     }
 
     fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
-        let datetime = self.utc_datetime.utc_to_offset(self.offset);
-        let offset = self.offset;
-
-        let shrunk_datetime = datetime
-            .shrink()
-            .map(move |datetime| datetime.assume_offset(offset));
-        let shrunk_offset = offset
-            .shrink()
-            .map(move |offset| datetime.assume_offset(offset));
-
-        Box::new(shrunk_datetime.chain(shrunk_offset))
+        Box::new(
+            (self.utc_datetime.utc_to_offset(self.offset), self.offset)
+                .shrink()
+                .map(|(utc_datetime, offset)| utc_datetime.assume_offset(offset)),
+        )
     }
 }
 
 #[cfg_attr(__time_03_docs, doc(cfg(feature = "quickcheck")))]
 impl Arbitrary for Weekday {
-    fn arbitrary<G: Gen>(g: &mut G) -> Self {
+    fn arbitrary(g: &mut Gen) -> Self {
         use Weekday::*;
-        match g.gen_range(0, g.size().clamp_(1, 7)) {
+        match arbitrary_between::<u8>(g, 0, 6) {
             0 => Monday,
             1 => Tuesday,
             2 => Wednesday,
@@ -286,8 +250,8 @@ impl Arbitrary for Weekday {
 
     fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
         match self {
-            Self::Monday => Box::new(iter::empty()),
-            _ => Box::new(iter::once(self.previous())),
+            Self::Monday => empty_shrinker(),
+            _ => single_shrinker(self.previous()),
         }
     }
 }
diff --git a/src/rand.rs b/src/rand.rs
index fda1c7680..463abe30e 100644
--- a/src/rand.rs
+++ b/src/rand.rs
@@ -13,10 +13,10 @@ use rand::{
 impl Distribution<Time> for Standard {
     fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Time {
         Time {
-            hour: rng.gen_range(0, 24),
-            minute: rng.gen_range(0, 60),
-            second: rng.gen_range(0, 60),
-            nanosecond: rng.gen_range(0, 1_000_000_000),
+            hour: rng.gen_range(0..24),
+            minute: rng.gen_range(0..60),
+            second: rng.gen_range(0..60),
+            nanosecond: rng.gen_range(0..1_000_000_000),
             padding: hack::Padding::Optimize,
         }
     }
@@ -29,7 +29,7 @@ impl Distribution<Date> for Standard {
         let max_date = Date::from_ordinal_date_unchecked(MAX_YEAR, util::days_in_year(MAX_YEAR));
 
         match Date::from_julian_day(
-            rng.gen_range(min_date.to_julian_day(), max_date.to_julian_day() + 1),
+            rng.gen_range(min_date.to_julian_day()..=max_date.to_julian_day()),
         ) {
             Ok(date) => date,
             Err(_) => unreachable!("The value is guaranteed to be in the range of valid dates."),
@@ -40,9 +40,9 @@ impl Distribution<Date> for Standard {
 #[cfg_attr(__time_03_docs, doc(cfg(feature = "rand")))]
 impl Distribution<UtcOffset> for Standard {
     fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> UtcOffset {
-        let hours = rng.gen_range(-23, 24);
-        let mut minutes = rng.gen_range(0, 60);
-        let mut seconds = rng.gen_range(0, 60);
+        let hours = rng.gen_range(-23..24);
+        let mut minutes = rng.gen_range(0..60);
+        let mut seconds = rng.gen_range(0..60);
 
         if hours < 0 {
             minutes *= -1;
@@ -78,7 +78,7 @@ impl Distribution<Duration> for Standard {
         let seconds = Self.sample(rng);
         Duration {
             seconds,
-            nanoseconds: seconds.signum() as i32 * rng.gen_range(0, 1_000_000_000),
+            nanoseconds: seconds.signum() as i32 * rng.gen_range(0..1_000_000_000),
         }
     }
 }
@@ -88,7 +88,7 @@ impl Distribution<Weekday> for Standard {
     fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Weekday {
         use Weekday::*;
 
-        match rng.gen_range(0, 7) {
+        match rng.gen_range(0..7) {
             0 => Monday,
             1 => Tuesday,
             2 => Wednesday,
diff --git a/src/serde/timestamp.rs b/src/serde/timestamp.rs
index fb55cf416..64effc544 100644
--- a/src/serde/timestamp.rs
+++ b/src/serde/timestamp.rs
@@ -85,6 +85,7 @@ pub fn deserialize<'a, D: Deserializer<'a>>(deserializer: D) -> Result<OffsetDat
 /// [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time
 /// [with]: https://serde.rs/field-attrs.html#with
 pub mod option {
+    #[allow(clippy::wildcard_imports)]
     use super::*;
 
     #[derive(Serialize, Deserialize)]
diff --git a/src/time.rs b/src/time.rs
index 85fb288af..adf3717a7 100644
--- a/src/time.rs
+++ b/src/time.rs
@@ -98,12 +98,7 @@ impl Time {
     /// assert!(Time::from_hms(0, 60, 0).is_err()); // 60 isn't a valid minute.
     /// assert!(Time::from_hms(0, 0, 60).is_err()); // 60 isn't a valid second.
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn from_hms(hour: u8, minute: u8, second: u8) -> Result<Self, error::ComponentRange> {
+    pub const fn from_hms(hour: u8, minute: u8, second: u8) -> Result<Self, error::ComponentRange> {
         ensure_value_in_range!(hour in 0 => 23);
         ensure_value_in_range!(minute in 0 => 59);
         ensure_value_in_range!(second in 0 => 59);
@@ -130,12 +125,7 @@ impl Time {
     /// assert!(Time::from_hms_milli(0, 0, 60, 0).is_err()); // 60 isn't a valid second.
     /// assert!(Time::from_hms_milli(0, 0, 0, 1_000).is_err()); // 1_000 isn't a valid millisecond.
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn from_hms_milli(
+    pub const fn from_hms_milli(
         hour: u8,
         minute: u8,
         second: u8,
@@ -168,12 +158,7 @@ impl Time {
     /// assert!(Time::from_hms_micro(0, 0, 60, 0).is_err()); // 60 isn't a valid second.
     /// assert!(Time::from_hms_micro(0, 0, 0, 1_000_000).is_err()); // 1_000_000 isn't a valid microsecond.
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn from_hms_micro(
+    pub const fn from_hms_micro(
         hour: u8,
         minute: u8,
         second: u8,
@@ -206,12 +191,7 @@ impl Time {
     /// assert!(Time::from_hms_nano(0, 0, 60, 0).is_err()); // 60 isn't a valid second.
     /// assert!(Time::from_hms_nano(0, 0, 0, 1_000_000_000).is_err()); // 1_000_000_000 isn't a valid nanosecond.
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn from_hms_nano(
+    pub const fn from_hms_nano(
         hour: u8,
         minute: u8,
         second: u8,
@@ -366,8 +346,7 @@ impl Time {
     /// Add the sub-day time of the [`Duration`] to the `Time`. Wraps on overflow, returning the
     /// necessary whether the date is the following day.
     #[allow(clippy::manual_range_contains)] // rust-lang/rust-clippy#6373
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub(crate) fn adjusting_add(self, duration: Duration) -> (DateAdjustment, Self) {
+    pub(crate) const fn adjusting_add(self, duration: Duration) -> (DateAdjustment, Self) {
         let mut nanoseconds = self.nanosecond as i32 + duration.subsec_nanoseconds();
         let mut seconds = self.second as i8 + (duration.whole_seconds() % 60) as i8;
         let mut minutes = self.minute as i8 + (duration.whole_minutes() % 60) as i8;
@@ -428,8 +407,7 @@ impl Time {
 
     /// Add the sub-day time of the [`std::time::Duration`] to the `Time`. Wraps on overflow,
     /// returning whether the date is the previous date as the first element of the tuple.
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub(crate) fn adjusting_add_std(self, duration: StdDuration) -> (bool, Self) {
+    pub(crate) const fn adjusting_add_std(self, duration: StdDuration) -> (bool, Self) {
         let mut nanosecond = self.nanosecond + duration.subsec_nanos();
         let mut second = self.second + (duration.as_secs() % 60) as u8;
         let mut minute = self.minute + ((duration.as_secs() / 60) % 60) as u8;
@@ -470,8 +448,7 @@ impl Time {
 
     /// Subtract the sub-day time of the [`std::time::Duration`] to the `Time`. Wraps on overflow,
     /// returning whether the date is the previous date as the first element of the tuple.
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub(crate) fn adjusting_sub_std(self, duration: StdDuration) -> (bool, Self) {
+    pub(crate) const fn adjusting_sub_std(self, duration: StdDuration) -> (bool, Self) {
         let mut nanosecond = self.nanosecond as i32 - duration.subsec_nanos() as i32;
         let mut second = self.second as i8 - (duration.as_secs() % 60) as i8;
         let mut minute = self.minute as i8 - ((duration.as_secs() / 60) % 60) as i8;
diff --git a/src/utc_offset.rs b/src/utc_offset.rs
index 3b47afb75..0f2e7f32b 100644
--- a/src/utc_offset.rs
+++ b/src/utc_offset.rs
@@ -68,12 +68,7 @@ impl UtcOffset {
     /// assert_eq!(UtcOffset::from_hms(1, -2, -3)?.as_hms(), (1, 2, 3));
     /// # Ok::<_, time::Error>(())
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn from_hms(
+    pub const fn from_hms(
         hours: i8,
         mut minutes: i8,
         mut seconds: i8,
diff --git a/src/util.rs b/src/util.rs
index a59c21e1f..052f551c0 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -17,8 +17,7 @@ const DAYS_IN_MONTH_COMMON_LEAP: [[u8; 12]; 2] = [
 ];
 
 /// Get the number of days in the month of a given year.
-#[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-pub(crate) fn days_in_year_month(year: i32, month: u8) -> u8 {
+pub(crate) const fn days_in_year_month(year: i32, month: u8) -> u8 {
     DAYS_IN_MONTH_COMMON_LEAP[is_leap_year(year) as usize][month as usize - 1]
 }
 
@@ -33,12 +32,7 @@ pub(crate) fn days_in_year_month(year: i32, month: u8) -> u8 {
 /// assert!(!is_leap_year(2005));
 /// assert!(!is_leap_year(2100));
 /// ```
-#[cfg_attr(
-    feature = "const_fn",
-    doc = "This feature is `const fn` when using rustc >= 1.46."
-)]
-#[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-pub fn is_leap_year(year: i32) -> bool {
+pub const fn is_leap_year(year: i32) -> bool {
     year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
 }
 
@@ -54,12 +48,7 @@ pub fn is_leap_year(year: i32) -> bool {
 /// assert_eq!(days_in_year(2005), 365);
 /// assert_eq!(days_in_year(2100), 365);
 /// ```
-#[cfg_attr(
-    feature = "const_fn",
-    doc = "This feature is `const fn` when using rustc >= 1.46."
-)]
-#[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-pub fn days_in_year(year: i32) -> u16 {
+pub const fn days_in_year(year: i32) -> u16 {
     if is_leap_year(year) { 366 } else { 365 }
 }
 
@@ -72,12 +61,7 @@ pub fn days_in_year(year: i32) -> u16 {
 /// assert_eq!(weeks_in_year(2019), 52);
 /// assert_eq!(weeks_in_year(2020), 53);
 /// ```
-#[cfg_attr(
-    feature = "const_fn",
-    doc = "This feature is `const fn` when using rustc >= 1.46."
-)]
-#[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-pub fn weeks_in_year(year: i32) -> u8 {
+pub const fn weeks_in_year(year: i32) -> u8 {
     let mut within_period = year % 400;
     if within_period < 0 {
         within_period += 400;
diff --git a/src/weekday.rs b/src/weekday.rs
index ce632315e..29bdf22c9 100644
--- a/src/weekday.rs
+++ b/src/weekday.rs
@@ -35,12 +35,7 @@ impl Weekday {
     /// # use time::Weekday;
     /// assert_eq!(Weekday::Tuesday.previous(), Weekday::Monday);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn previous(self) -> Self {
+    pub const fn previous(self) -> Self {
         match self {
             Monday => Sunday,
             Tuesday => Monday,
@@ -58,12 +53,7 @@ impl Weekday {
     /// # use time::Weekday;
     /// assert_eq!(Weekday::Monday.next(), Weekday::Tuesday);
     /// ```
-    #[cfg_attr(
-        feature = "const_fn",
-        doc = "This feature is `const fn` when using rustc >= 1.46."
-    )]
-    #[cfg_attr(feature = "const_fn", const_fn::const_fn("1.46"))]
-    pub fn next(self) -> Self {
+    pub const fn next(self) -> Self {
         match self {
             Monday => Tuesday,
             Tuesday => Wednesday,
diff --git a/time-benchmarks/Cargo.toml b/time-benchmarks/Cargo.toml
index e7f9b21da..af6a3982a 100644
--- a/time-benchmarks/Cargo.toml
+++ b/time-benchmarks/Cargo.toml
@@ -11,8 +11,8 @@ description = "Benchmarks for the time crate."
 [dev-dependencies]
 criterion = "0.3.3"
 bench-util = { path = "./bench-util" }
-rand = { version = "0.7.3", default-features = false }
-serde_json = "1.0.59"
+rand = { version = "0.8.1", default-features = false }
+serde_json = "1.0.61"
 time = { path = "..", features = ["local-offset", "macros", "rand", "serde"] }
 
 [[bench]]
diff --git a/time-macros-impl/Cargo.toml b/time-macros-impl/Cargo.toml
deleted file mode 100644
index 589751a70..000000000
--- a/time-macros-impl/Cargo.toml
+++ /dev/null
@@ -1,20 +0,0 @@
-[package]
-name = "time-macros-impl"
-version = "0.2.0-dev"
-authors = ["Jacob Pratt <open-source@jhpratt.dev>", "Time contributors"]
-edition = "2018"
-repository = "https://github.com/time-rs/time"
-keywords = ["date", "time", "calendar", "duration"]
-categories = ["date-and-time"]
-readme = "../README.md"
-license = "MIT OR Apache-2.0"
-description = "Procedural macros for the time crate."
-
-[features]
-large-dates = []
-
-[dependencies]
-proc-macro-hack = "0.5.19"
-
-[lib]
-proc-macro = true
diff --git a/time-macros-impl/LICENSE-Apache b/time-macros-impl/LICENSE-Apache
deleted file mode 120000
index 0cd69a3e2..000000000
--- a/time-macros-impl/LICENSE-Apache
+++ /dev/null
@@ -1,1 +0,0 @@
-../LICENSE-Apache
\ No newline at end of file
diff --git a/time-macros-impl/LICENSE-MIT b/time-macros-impl/LICENSE-MIT
deleted file mode 120000
index 76219eb72..000000000
--- a/time-macros-impl/LICENSE-MIT
+++ /dev/null
@@ -1,1 +0,0 @@
-../LICENSE-MIT
\ No newline at end of file
diff --git a/time-macros/Cargo.toml b/time-macros/Cargo.toml
index 490a56b8c..6369804e7 100644
--- a/time-macros/Cargo.toml
+++ b/time-macros/Cargo.toml
@@ -10,12 +10,8 @@ readme = "../README.md"
 license = "MIT OR Apache-2.0"
 description = "Procedural macros for the time crate."
 
-[lib]
-path = "lib.rs"
-
 [features]
-large-dates = ["time-macros-impl/large-dates"]
+large-dates = []
 
-[dependencies]
-time-macros-impl = { version = "=0.2.0-dev", path = "../time-macros-impl" }
-proc-macro-hack = "0.5.19"
+[lib]
+proc-macro = true
diff --git a/time-macros/lib.rs b/time-macros/lib.rs
deleted file mode 100644
index f10668515..000000000
--- a/time-macros/lib.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![no_std]
-
-use proc_macro_hack::proc_macro_hack;
-
-#[proc_macro_hack]
-pub use time_macros_impl::{date, datetime, offset, time};
diff --git a/time-macros-impl/src/date.rs b/time-macros/src/date.rs
similarity index 100%
rename from time-macros-impl/src/date.rs
rename to time-macros/src/date.rs
diff --git a/time-macros-impl/src/datetime.rs b/time-macros/src/datetime.rs
similarity index 100%
rename from time-macros-impl/src/datetime.rs
rename to time-macros/src/datetime.rs
diff --git a/time-macros-impl/src/error.rs b/time-macros/src/error.rs
similarity index 100%
rename from time-macros-impl/src/error.rs
rename to time-macros/src/error.rs
diff --git a/time-macros-impl/src/helpers.rs b/time-macros/src/helpers.rs
similarity index 100%
rename from time-macros-impl/src/helpers.rs
rename to time-macros/src/helpers.rs
diff --git a/time-macros-impl/src/lib.rs b/time-macros/src/lib.rs
similarity index 95%
rename from time-macros-impl/src/lib.rs
rename to time-macros/src/lib.rs
index e5062d89d..388d89b43 100644
--- a/time-macros-impl/src/lib.rs
+++ b/time-macros/src/lib.rs
@@ -36,9 +36,6 @@
     clippy::redundant_pub_crate
 )]
 
-#[allow(unused_extern_crates)]
-extern crate proc_macro;
-
 mod date;
 mod datetime;
 mod error;
@@ -52,7 +49,6 @@ use datetime::DateTime;
 use error::Error;
 use offset::Offset;
 use proc_macro::TokenStream;
-use proc_macro_hack::proc_macro_hack;
 use time::Time;
 
 trait ToTokens {
@@ -75,7 +71,7 @@ trait ToTokens {
 macro_rules! impl_macros {
     ($($name:ident : $type:ty)*) => {$(
         #[allow(clippy::unimplemented)] // macro-generated
-        #[proc_macro_hack]
+        #[proc_macro]
         pub fn $name(input: TokenStream) -> TokenStream {
             let string = match helpers::get_string_literal(input) {
                 Ok(string) => string,
diff --git a/time-macros-impl/src/offset.rs b/time-macros/src/offset.rs
similarity index 100%
rename from time-macros-impl/src/offset.rs
rename to time-macros/src/offset.rs
diff --git a/time-macros-impl/src/peeking_take_while.rs b/time-macros/src/peeking_take_while.rs
similarity index 100%
rename from time-macros-impl/src/peeking_take_while.rs
rename to time-macros/src/peeking_take_while.rs
diff --git a/time-macros-impl/src/time.rs b/time-macros/src/time.rs
similarity index 100%
rename from time-macros-impl/src/time.rs
rename to time-macros/src/time.rs


Test patch:
diff --git a/tests/quickcheck.rs b/tests/quickcheck.rs
index e33db4539..1f554a4c7 100644
--- a/tests/quickcheck.rs
+++ b/tests/quickcheck.rs
@@ -1,68 +1,8 @@
 #![cfg(feature = "quickcheck")]
 
-use quickcheck_dep::{quickcheck, Arbitrary, QuickCheck, StdGen, TestResult};
-use rand::{rngs::StdRng, SeedableRng};
+use quickcheck_dep::{quickcheck, Arbitrary, TestResult};
 use time::{Date, Duration, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset, Weekday};
 
-/// Returns a statically seeded generator to ensure tests are deterministic
-fn make_generator(size: usize) -> StdGen<StdRng> {
-    StdGen::new(StdRng::from_seed([0; 32]), size)
-}
-
-macro_rules! test_generator_size {
-    ($type:ty,
-     $($($method:ident()).+ $(min=$min_value:literal)?),+,
-     $size:literal
-    ) => {{
-        let mut q = QuickCheck::with_gen(make_generator($size));
-        let mut g = make_generator($size);
-
-        $(
-            // Check that size sets upper bound.
-            // We check that the generated value is bounded by the requested
-            // size. If $min_value is present, then that is also an accepted
-            // value even if numerically greater than the size.
-            q.quickcheck((|v: $type| {
-                let value = v.$($method()).+;
-                value <= $size $(|| value == $min_value)?
-            }) as fn($type) -> bool);
-
-            // Check that full range is used
-            let mut found_small_value = false;
-            let mut found_large_value = false;
-            let mut iterations = 0;
-
-            while !(found_small_value && found_large_value) && iterations <= $size * 2 {
-                iterations += 1;
-
-                let v = <$type>::arbitrary(&mut g);
-                let value = v$(.$method())+;
-                if value <= $size / 4 $(|| value == $min_value)? {
-                    found_small_value = true;
-                }
-                if value >= $size / 2 {
-                    found_large_value = true;
-                }
-            }
-
-            assert!(
-                found_small_value,
-                "Found no small value for {} {} at size {}",
-                stringify!($type),
-                stringify!($(.$method())+),
-                stringify!($size),
-            );
-            assert!(
-                found_large_value,
-                "Found no large value for {} {} at size {}",
-                stringify!($type),
-                stringify!($(.$method())+),
-                stringify!($size),
-            );
-        )+
-    }};
-}
-
 macro_rules! test_shrink {
     ($type:ty,
      $fn_name:ident,
@@ -75,10 +15,13 @@ macro_rules! test_shrink {
                 if method_value == 0 $(|| method_value == $min_value)? {
                     TestResult::discard()
                 } else {
-                    TestResult::from_bool(
-                        v.shrink()
-                            .any(|shrunk|
-                                 shrunk.$($method()).+ < v.$($method()).+))
+                    TestResult::from_bool(v.shrink().any(|shrunk|
+                        if method_value > 0 {
+                            shrunk.$($method()).+ < v.$($method()).+
+                        } else {
+                            shrunk.$($method()).+ > v.$($method()).+
+                        }
+                    ))
                 }
             }
         }
@@ -86,81 +29,58 @@ macro_rules! test_shrink {
 }
 
 quickcheck! {
-    fn date_supports_arbitrary(d: Date) -> bool {
-        Date::from_calendar_date(d.year(), d.month(), d.day()) == Ok(d)
+    fn date_roundtrip(d: Date) -> bool {
+        Date::from_ordinal_date(d.year(), d.ordinal()) == Ok(d)
     }
-}
-test_shrink!(Date, date_can_shrink_year, year().abs());
-test_shrink!(Date, date_can_shrink_ordinal, ordinal(), min = 1);
 
-#[test]
-fn arbitrary_date_respects_generator_size() {
-    test_generator_size!(Date, year().abs(), 0);
-    test_generator_size!(Date, year().abs(), 1);
-    test_generator_size!(Date, year().abs(), 100);
-    test_generator_size!(Date, year().abs(), 10_000);
-    #[cfg(feature = "large-dates")]
-    test_generator_size!(Date, year().abs(), 100_000);
+    fn duration_roundtrip(d: Duration) -> bool {
+        Duration::new(d.whole_seconds(), d.subsec_nanoseconds()) == d
+    }
 
-    test_generator_size!(Date, ordinal() min=1, 1);
-    test_generator_size!(Date, ordinal(), 10);
-    test_generator_size!(Date, ordinal(), 100);
-    test_generator_size!(Date, ordinal(), 366);
-}
+    fn time_roundtrip(t: Time) -> bool {
+        Time::from_hms_nano(t.hour(), t.minute(), t.second(), t.nanosecond()) == Ok(t)
+    }
 
-quickcheck! {
-    fn duration_supports_arbitrary(d: Duration) -> bool {
-        Duration::new(d.whole_seconds(), d.subsec_nanoseconds()) == d
+    fn primitive_date_time_roundtrip(a: PrimitiveDateTime) -> bool {
+        PrimitiveDateTime::new(a.date(), a.time()) == a
     }
-}
-test_shrink!(Duration, duration_can_shrink_seconds, whole_seconds().abs());
-test_shrink!(Duration, duration_can_shrink_ns, subsec_nanoseconds().abs());
 
-#[test]
-fn arbitrary_duration_respects_generator_size() {
-    test_generator_size!(Duration, whole_seconds().abs(), 0);
-    test_generator_size!(Duration, whole_seconds().abs(), 1);
-    test_generator_size!(Duration, whole_seconds().abs(), 1000);
-    test_generator_size!(Duration, whole_seconds().abs(), 1_000_000);
-    test_generator_size!(Duration, whole_seconds().abs(), 1_000_000_000);
+    fn utc_offset_roundtrip(o: UtcOffset) -> bool {
+        let (hours, minutes, seconds) = o.as_hms();
+        UtcOffset::from_hms(hours, minutes, seconds) == Ok(o)
+    }
 
-    test_generator_size!(Duration, subsec_nanoseconds().abs(), 0);
-    test_generator_size!(Duration, subsec_nanoseconds().abs(), 1);
-    test_generator_size!(Duration, subsec_nanoseconds().abs(), 1000);
-    test_generator_size!(Duration, subsec_nanoseconds().abs(), 1_000_000);
-    test_generator_size!(Duration, subsec_nanoseconds().abs(), 1_000_000_000);
-}
+    fn offset_date_time_roundtrip(a: OffsetDateTime) -> bool {
+        PrimitiveDateTime::new(a.date(), a.time()).assume_offset(a.offset()) == a
+    }
 
-quickcheck! {
-    fn time_supports_arbitrary(t: Time) -> bool {
-        Time::from_hms_nano(t.hour(), t.minute(), t.second(), t.nanosecond()) == Ok(t)
+    fn weekday_supports_arbitrary(w: Weekday) -> bool {
+        (1..=7).contains(&w.iso_weekday_number())
+    }
+
+    fn weekday_can_shrink(w: Weekday) -> bool {
+        match w {
+            Weekday::Monday => w.shrink().next() == None,
+            _ => w.shrink().next() == Some(w.previous())
+        }
     }
 }
+
+test_shrink!(Date, date_can_shrink_year, year());
+test_shrink!(Date, date_can_shrink_ordinal, ordinal(), min = 1);
+
+test_shrink!(Duration, duration_can_shrink_seconds, whole_seconds());
+test_shrink!(Duration, duration_can_shrink_ns, subsec_nanoseconds());
+
 test_shrink!(Time, time_can_shrink_hour, hour());
 test_shrink!(Time, time_can_shrink_minute, minute());
 test_shrink!(Time, time_can_shrink_second, second());
 test_shrink!(Time, time_can_shrink_nanosecond, nanosecond());
 
-#[test]
-fn arbitrary_time_respects_generator_size() {
-    test_generator_size!(Time, nanosecond(), second(), minute(), hour(), 0);
-    test_generator_size!(Time, nanosecond(), second(), minute(), hour(), 1);
-    test_generator_size!(Time, nanosecond(), second(), minute(), hour(), 10);
-    test_generator_size!(Time, nanosecond(), second(), minute(), 100);
-    test_generator_size!(Time, nanosecond(), 1000);
-    test_generator_size!(Time, nanosecond(), 1_000_000);
-    test_generator_size!(Time, nanosecond(), 1_000_000_000);
-}
-
-quickcheck! {
-    fn primitive_date_time_supports_arbitrary(a: PrimitiveDateTime) -> bool {
-        PrimitiveDateTime::new(a.date(), a.time()) == a
-    }
-}
 test_shrink!(
     PrimitiveDateTime,
     primitive_date_time_can_shrink_year,
-    year().abs()
+    year()
 );
 test_shrink!(
     PrimitiveDateTime,
@@ -189,62 +109,14 @@ test_shrink!(
     nanosecond()
 );
 
-#[test]
-fn arbitrary_primitive_date_time_respects_generator_size() {
-    test_generator_size!(PrimitiveDateTime, year().abs(), 0);
-    test_generator_size!(PrimitiveDateTime, year().abs(), 1);
-    test_generator_size!(PrimitiveDateTime, year().abs(), 100);
-    test_generator_size!(PrimitiveDateTime, year().abs(), 10_000);
-    #[cfg(feature = "large-dates")]
-    test_generator_size!(PrimitiveDateTime, year().abs(), 100_000);
-
-    test_generator_size!(PrimitiveDateTime, ordinal() min=1, 0);
-    test_generator_size!(PrimitiveDateTime, ordinal() min=1, 1);
-    test_generator_size!(PrimitiveDateTime, ordinal() min=1, 10);
-    test_generator_size!(PrimitiveDateTime, ordinal() min=1, 100);
-    test_generator_size!(PrimitiveDateTime, ordinal() min=1, 366);
-
-    test_generator_size!(PrimitiveDateTime, second(), minute(), hour(), 0);
-    test_generator_size!(PrimitiveDateTime, second(), minute(), hour(), 1);
-    test_generator_size!(PrimitiveDateTime, second(), minute(), hour(), 10);
-    test_generator_size!(PrimitiveDateTime, second(), minute(), 100);
-    test_generator_size!(PrimitiveDateTime, nanosecond(), 1);
-    test_generator_size!(PrimitiveDateTime, nanosecond(), 1000);
-    test_generator_size!(PrimitiveDateTime, nanosecond(), 1_000_000);
-    test_generator_size!(PrimitiveDateTime, nanosecond(), 1_000_000_000);
-}
-
-quickcheck! {
-    fn utc_offset_supports_arbitrary(o: UtcOffset) -> bool {
-        let (hours, minutes, seconds) = o.as_hms();
-        UtcOffset::from_hms(hours, minutes, seconds) == Ok(o)
-    }
-}
-test_shrink!(UtcOffset, utc_offset_can_shrink, to_seconds().abs());
-
-#[test]
-fn arbitrary_utc_offset_respects_generator_size() {
-    test_generator_size!(UtcOffset, to_seconds(), 0);
-    test_generator_size!(UtcOffset, to_seconds(), 1);
-    test_generator_size!(UtcOffset, to_seconds(), 1_000);
-    test_generator_size!(UtcOffset, to_seconds(), 100_000);
-}
+test_shrink!(UtcOffset, utc_offset_can_shrink, to_seconds());
 
-quickcheck! {
-    fn offset_date_time_supports_arbitrary(a: OffsetDateTime) -> bool {
-        PrimitiveDateTime::new(a.date(), a.time()).assume_offset(a.offset()) == a
-    }
-}
 test_shrink!(
     OffsetDateTime,
     offset_date_time_can_shrink_offset,
-    offset().to_seconds().abs()
-);
-test_shrink!(
-    OffsetDateTime,
-    offset_date_time_can_shrink_year,
-    year().abs()
+    offset().to_seconds()
 );
+test_shrink!(OffsetDateTime, offset_date_time_can_shrink_year, year());
 test_shrink!(
     OffsetDateTime,
     offset_date_time_can_shrink_ordinal,
@@ -259,58 +131,3 @@ test_shrink!(
     offset_date_time_can_shrink_nanosecond,
     nanosecond()
 );
-
-#[test]
-fn arbitrary_offset_date_time_respects_generator_size() {
-    test_generator_size!(OffsetDateTime, year().abs(), 0);
-    test_generator_size!(OffsetDateTime, year().abs(), 1);
-    test_generator_size!(OffsetDateTime, year().abs(), 100);
-    test_generator_size!(OffsetDateTime, year().abs(), 10_000);
-    #[cfg(feature = "large-dates")]
-    test_generator_size!(OffsetDateTime, year().abs(), 100_000);
-
-    test_generator_size!(OffsetDateTime, ordinal() min=1, 0);
-    test_generator_size!(OffsetDateTime, ordinal() min=1, 1);
-    test_generator_size!(OffsetDateTime, ordinal() min=1, 10);
-    test_generator_size!(OffsetDateTime, ordinal() min=1, 100);
-    test_generator_size!(OffsetDateTime, ordinal() min=1, 366);
-
-    test_generator_size!(OffsetDateTime, second(), minute(), hour(), 0);
-    test_generator_size!(OffsetDateTime, second(), minute(), hour(), 1);
-    test_generator_size!(OffsetDateTime, second(), minute(), hour(), 10);
-    test_generator_size!(OffsetDateTime, second(), minute(), 100);
-    test_generator_size!(OffsetDateTime, nanosecond(), 1);
-    test_generator_size!(OffsetDateTime, nanosecond(), 1000);
-    test_generator_size!(OffsetDateTime, nanosecond(), 1_000_000);
-    test_generator_size!(OffsetDateTime, nanosecond(), 1_000_000_000);
-
-    test_generator_size!(OffsetDateTime, offset().to_seconds().abs(), 0);
-    test_generator_size!(OffsetDateTime, offset().to_seconds().abs(), 1);
-    test_generator_size!(OffsetDateTime, offset().to_seconds().abs(), 1000);
-    test_generator_size!(OffsetDateTime, offset().to_seconds().abs(), 100_000);
-}
-
-quickcheck! {
-    fn weekday_supports_arbitrary(w: Weekday) -> bool {
-        w.iso_weekday_number() >= 1 && w.iso_weekday_number() <= 7
-    }
-
-    fn weekday_can_shrink(w: Weekday) -> bool {
-        match w {
-            Weekday::Monday => w.shrink().next() == None,
-            _ => w.shrink().next() == Some(w.previous())
-        }
-    }
-}
-
-#[test]
-fn arbitrary_weekday_respects_generator_size() {
-    test_generator_size!(Weekday, iso_weekday_number() min=1, 0);
-    test_generator_size!(Weekday, iso_weekday_number() min=1, 1);
-    test_generator_size!(Weekday, iso_weekday_number() min=1, 2);
-    test_generator_size!(Weekday, iso_weekday_number() min=1, 3);
-    test_generator_size!(Weekday, iso_weekday_number() min=1, 4);
-    test_generator_size!(Weekday, iso_weekday_number() min=1, 5);
-    test_generator_size!(Weekday, iso_weekday_number() min=1, 6);
-    test_generator_size!(Weekday, iso_weekday_number() min=1, 7);
-}