[Question]
  [
Don't tell anyone, but I've nicked my uncle's time travel machine! My uncle is obsessed with prime numbers, though, and that shows in the machine — he has programmed it so that it can only go to dates that sum up to a prime number. 
So it can't go to `1947-08-15` because 1947+8+15 = 1970, which is not a prime number. It *can* go to `1947-07-25`, because 1947+7+25 = 1979, which is prime. So if I want to go back to watch India's independence celebrations, it looks like I'll have to go a few weeks earlier and wait out those 20 days. 
I have some other dates that I want to go to, and I'll similarly have to go to a date before (or if I'm lucky, equal to) my target date, that sums up to a prime number. I'm impatient, though, and don't want to wait too much — so I want to find the date I can use that is closest to my target date.
**Can you write me a program that takes my target date and gives me the date I should input into the time machine — the closest date before or equal to the given date whose parts add up to a prime number?**
(For this challenge, we're using the *proleptic* Gregorian calendar — which simply means we use the current Gregorian calendar even for periods when people then were using the older Julian calendar.)
### Input
* A date
	+ ideally, any date in the Current Era (AD); practically, whatever subset of that your language can naturally handle
	+ in any single human-readable format⁺ you like
### Output
* The date closest to the input date, which is less than or equal to the input and whose date+month+year sums up to a prime number.
	+ in any single human-readable format⁺ you like
⁺: "human readable" as in the day, month and year all separately spelt out, in whatever order
### Test cases
```
1947-08-15
=> 1947-07-25
1957-10-04
=> 1957-09-27
1776-07-04
=> 1776-07-04
999-12-12
=> 0999-12-10
2018-06-20
=> 2018-06-15
1999-01-02
=> 1998-12-29
1319-12-29
=> 1319-07-01
```
*(Thanks to @Shaggy, @PeterTaylor, and @Arnauld for help with the question.)*
  
[Answer]
# [Red](http://www.red-lang.org), 87 bytes
```
func[d][d: d + 1 until[d: d - 1 n: d/2 + d/3 + d/4 i: 1 until[n %(i: i + 1)= 0]i = n]d]
```
[Try it online!](https://tio.run/##TYvRCsIwDEXf9xV5ERQJa2q3roX9hK@lT2aFghQZ2/d3UbEIIeSce7MuXO8Lh9glX9NeHoFjYA8MVyDYy5afX0TBIkevJeH@9tkGsm@1AqezYH5/XmZQMcMMJXKsrzWXDRLQgBOSM7b7GYOkxAz/xiJZOzZBGmWcc81ohSNqRVM9AA "Red – Try It Online")
## More readable:
```
f: func [ d ] [ 
    d: d + 1
    until [
        d: d - 1
        n: d/day + d/month + d/year
        i: 1
        until [
            i: i + 1
            n % i = 0
        ]
        i = n
    ] 
    d
]
```
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 94 bytes
Takes input as 3 integers in currying syntax `(year)(month)(day)`. Returns a hyphen-separated string with a leading hyphen.
```
y=>m=>g=d=>(P=k=>n%++k?P(k):~k)(n=eval(s='-'+new Date(y,m-1,d).toJSON().split`T`[0]))?g(d-1):s
```
[Try it online!](https://tio.run/##Zc5Ba8JAEAXge3/FXoozxIk728R1hY2XnnpohXorBYOJwSYm0gSLl/71dDdVKOnhXR4fj/eRntN293k4dVQ3Wd7vbX@xydEmhc1sAmtb2qS@D4JytYYSl98lQm3zc1pBayc0Cer8SzymXQ6X6ZF4mmHYNU@vL8@AYXuqDt12s32T74irAjJiXLb9rqnbpsrDqilgD2wijSAWCBwjitlM@IakJhXfjWnsKEvHoxuNHTWk9JhqPXdM/6Gu8asyGlFhjHGrashApWuIFbEcUSXZ/RRuWclf6huSc@L/X/2qYBd1@2oWflWZMX3g6wFlrtQ1w1fufwA "JavaScript (Node.js) – Try It Online")
### How?
We first convert the date to JSON format `yyyy-mm-ddT00:00:00.000Z` ([ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)), split it on the `'T'`, keep only the left part and add a leading hyphen, which gives `-yyyy-mm-dd`.
```
s = '-' + new Date(y, m - 1, d).toJSON().split`T`[0]
```
This expression **s** can now be `eval()`'uated to get the opposite **n** of the sum of **year + month + day**.
```
n = eval(s)
```
We use the helper function **P()** to test whether **-n** is prime (in which case it returns **0**). If it is, we return **s**. Otherwise, we try again with the previous day.
```
(P = k => n % ++k ? P(k) : ~k)(n) ? g(d - 1) : s
```
[Answer]
# [Ruby](https://www.ruby-lang.org/en/), 94 bytes
[Try it online!](https://tio.run/##bclPC4IwHMbxu69iNzf6NTZR5w7VpXcREpMtGuGf5kREfe1LOnRJeODLw8cN1RQUOqFwPGNNZk11Oza@xYzMi10qZ9QLWerbe4/sA2FLtZoOltZt459bJ6McoZ2ztbmsa@TMe7DOxFp5E//el@PQDb5H6nbdjDZmxFymAgrgGSmjf8sEcAYs3UMhchD7JqUEnmzbsYTxAnJIGCnDBw)
Takes a single Date input, and returns a string in the ISO 8601 format (`YYYY-MM-DD`).
```
require'date'
require'prime'
->d{d.downto(0){|i|break i.to_s if (i.day+i.month+i.year).prime?}}
```
It uses Ruby's prime module. If that's not allowed, or frowned upon, then for two bytes more I present this abomination:
---
# [Ruby](https://www.ruby-lang.org/en/), 97 bytes
[Try it online!](https://tio.run/##bcnRCoIwGIbhc69igeCWa@4Xa3lQnnQXpTHZohFprYlI1q0vzxM@ePl4bFcPXqId8qs9VuStmGr7xrWYk/doxtpqeUOGufb8QuaCClhiw5QcYsPubeOuUwctLVl8UVJBEY4VBogLcoI4TD6fwOpnZ6yOlHQ68o/OvZA8HqbDGt1jyDNBtxTWpAz@bS0ocMqzORRiQ8W85XlOIZ02YymHLd3QlJPSe/8D)
It uses a check for a number being prime from [this stackoverflow answer](https://stackoverflow.com/a/19714987/4173627). I have no idea how this works, it looks a bit like witchcraft.
Same input as above, and same output.
```
require'date'
->d{d.downto(0){|i|break i.to_s if ?1*(i.day+i.month+i.year)!~ /^1?$|^(11+?)\1+$/}}
```
[Answer]
# [Python 2](https://docs.python.org/2/), ~~130~~ 127 bytes
Input is `year, month, day`.
-3 bytes thanks to [Kevin Cruijssen](https://codegolf.stackexchange.com/users/52210/kevin-cruijssen).
```
from datetime import*
def f(a):
  while(lambda n:any(n%m<1for m in range(2,n)))(a.year+a.month+a.day):a-=timedelta(1)
  print a
```
[Try it online!](https://tio.run/##Tc3BCsIwEATQe79iL0JWV2mCNrbox6wksYFmU0JA@vW1XlQYGHiHmXmpYxazrqHkBI6rrzF5iGnOpe4b5wMExTg0AK8xTl5NnB6OQQaWRcku3XTIBRJEgcLy9MqQIKLi0@K5HPiUstRxa8cLDny8f/adnyorjdvqXKJU4DWoz7nS/dnSlfQFsfnSxZJu6fxH1nZk/6Xve9Jmy49Mq6/UkWkR1zc "Python 2 – Try It Online")
[Answer]
# [R](https://www.r-project.org/), 117 bytes
```
function(d){while(!numbers::isPrime(y(d))){d=d-1};d}
`<`=format
y=function(d)sum(as.integer(c(d<"%Y",d<"%m",d<"%d")))
```
[Try it online!](https://tio.run/##ZY3BCoJAEIbvvkVCsEITM1aua3rrAbp209q1FlqFVYkIn93WupTCwA/zzf@NHcpsKLvq0uq6YjJ4PW76rtii6sxZ2SZJdHO02ij2dDAIXjKTQP1e9l6e5llZW1O03jP7MTSdYUWz1lWrrsqyC5Opvzz5qzHMN6TvVEM5nh2KVjGfxJYDxkA7R7w/sONACLidAs4jQD4HQgig0M1kHyLFgBGEOHvhGkiA0wZt6KMKhQPDGw "R – Try It Online")
[Answer]
# Java 8, ~~144~~ 128 bytes
```
d->{for(;;d=d.minusDays(1)){int n=d.getYear()+d.getMonthValue()+d.getDayOfMonth(),i=2;for(;i<n;n=n%i++<1?0:n);if(n>1)return d;}}
```
[Try it online.](https://tio.run/##pZDBTsMwDIbvewpfkBKti5pqo5Ss47IjG4dJSAhxCE06Mlp3atOhaeqzF6/AbachxYr9K/7y2zt90JOd@eyzQjcNrLTD0wjAobd1rjML63MJsKN3wrvSiscq08VSewsZu6Qarqijo6CzBoQUejNZnPKqZkqZ1IjSYdss9bFhkvMTfQVI6tb6F6trxsdDvqrQfzzrorV/CnU85YPMeODSSA1EN0eFKd648XguH8J75MrlDBeS19a3NYJRXderEZnZt@@Fy6Dx2tN1qJyBkuZlG1873L6@geY/w563ACUZR/s1FGyYCWBzbLwtRdV6saceXyArBYqLixBVzmQyjQO4C0DOOL@aMSOGDAMIp9dD4viWAPG/IEmSkJHoHFczolDSOkIyE4W/kG7U9d8)
`java.time.LocalDate` class has been an improvement in comparison to the old `java.util.Date`, but why did they had to make those names longer (`getMonthValue` and `getDayOfMonth` instead of `getMonth` and `getDay`).. >.>
**Explanation:**
```
d->{                      //  Method with LocalDate as both parameter and return-type
  for(;;                  //  Loop indefinitely
      d=d.minusDays(1)){  //    Going one day back after every iteration
    int n=d.getYear()+d.getMonthValue()+d.getDayOfMonth(),
                          //   Set `n` to the sum of year+month+day
    i=2;for(;i<n;n=n%i++<1?0:n);if(n>1)
                          //   If `n` is a prime:
      return d;}}         //    Return the now modified input-LocalDate `d`
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~57~~ 53 bytes
```
->d{d-=9until/^(11+)\1+$/!~?1*(d.day+d.year+d.mon);d}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf1y6lOkXX1rI0ryQzRz9Ow9BQWzPGUFtFX7HO3lBLI0UvJbFSO0WvMjWxCEjl5udpWqfU/i9QSIsOycxN1ctLLdcwtDQx17HQMTTVjOVCkzA11zE00DEwwZAxNzfTMcciYWlpqWNoBEToEkYGhhY6ZjpGBpiWgLToYGgwNDYEG2VkqRn7HwA "Ruby – Try It Online")
Not my idea - stolen from the "abomination" by IMP1
---
## Original idea:
# [Ruby](https://www.ruby-lang.org/), 59 bytes
```
->d{d-=9until((2...w=d.day+d.year+d.mon).all?{|x|w%x>0});d}
```
[Try it online!](https://tio.run/##bY3LCoMwFET3/YpuCoZeL7mpGkPR/kR3xYUlCoKPIpUY1G9PbZdaGJjF4cz0w9O6MnF@qiftJ2po31XteQIRTaJR5/as0RZ5v1bTtQzzur5N8zib05jyhV314l7H8nGvmgLbwnikAgkxUMiywwaEEogDD3ZEygjkH6CUAhJrtkBwiiECwfcnXwV2Al3oNyUUy9wH "Ruby – Try It Online")
[Answer]
# F#, 134 133 bytes
```
let rec s(d:System.DateTime)=
 let x=d.Year+d.Month+d.Day
 if(Seq.tryFind(fun i->x%i=0){2..x-1}).IsNone then d else d.AddDays(-1.)|>s
```
-1 byte thanks to from [sundar](https://codegolf.stackexchange.com/users/8774/sundar).
[Try it online!](https://tio.run/##bZBRS8MwFIXf@ysug0GLbWjqZq3agjAFH@aEiSBzD2G5dYE2nUmmHZu/vaZzc7AZuITk45577sl1MKsUNk2BBhTOQLv8arzSBksyYAafRYle6kCL65STV2TqjJNhJc3c3gO2ckDk7hg/iFGreyG5my8liCCruyINvXVESB3Qb4886MdKIpg5SuCAhUbg5JZzK6HdgBJvk@mmWlj6O96Z3NxJq/lUCWmyqdM6KJmQwNT7p3VkT/vFdyY1pDCR@AV71y5NerEPlz7QvncNR6hvEQ196J2gOL7wIf6HJElie6K2jlEUUjvH9kXh6ai2LaS2TtroOd1JRoll@38yZPULK5Y43W7ZZisMKtgmu98Xggz04bXJYKFsULmETnf0Zrqjzh/0DiFtBcPmBw)
Total the day, month and year and see if it's prime. If it is, return that date. If not, decrement the date by 1 day and try again.
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), ~~105~~ 90 bytes
```
for($a=$args[0];'1'*((Date $a -f yyyy+MM+dd)|iex)-match'^(..+)\1+$';$a=$a.AddDays(-1)){}$a
```
[Try it online!](https://tio.run/##HcxNCsIwEEDhq4QSyIxhglNXpbgQCq56An9gMKkVKpUmoEU9e5S@/fce4zNMsQ/DkHM3TqBlq2W6xsP6VBs2K4BGUlBaFHVq/mfb1nqPn1t4Id0lXXpzBucsHtlqUy/e7bxvZI5AjPj@ask5wz4kWl4Fb7giLqmsClQ/ "PowerShell – Try It Online")
*Thanks to sundar for -13 bytes.*
Takes input as a `DateTime` `2018-06-20` and saves it into `$a`. Then we're in a `for` loop. Each iteration, we're taking `$a` `-f`ormatted like `yyyy+MM+dd` (i.e., the current date we're on separated by `+` signs) added together with `|iex` (similar to `eval`), string-multiplying that with `1`s to form a unary number, and using a [prime-checking regex](https://codegolf.stackexchange.com/a/57636/42963) to determine if the current date is prime or not. If it is not prime, we `.AddDays(-1)` to go backwards a day and continue the loop. If it is prime, we break out of the loop and place `$a` onto the pipeline with implicit output.
The resulting output is culture-dependent. On TIO, which uses `en-us`, the output is long-date format, which looks like `Saturday, July 1, 1319 12:00:00 AM`.
[Answer]
# [Bash](https://www.gnu.org/software/bash/), ~~114~~ 108 bytes
```
a=`date +%s -d$1`
while [ "`date +%d+%m+%Y -d@$a|bc|factor|awk NF!=2`" ]
do a=$[a-86400]
done
date +%F -d@$a
```
[Try it online!](https://tio.run/##S0oszvj/P9E2ISWxJFVBW7VYQTdFxTCBqzwjMydVIVpBCSaRoq2aq60aCZR2UEmsSUquSUtMLskvqkksz1bwc1O0NUpQUojlSslXSLRViU7UtTAzMTAA8fNSuaAmuEH0/v//39DSxFzXwELX0BQA "Bash – Try It Online")
My first ever bash golf. Honestly, my first real bash program ever ... primality test taken from [here](https://codegolf.stackexchange.com/questions/57617/is-this-number-a-prime/57674#57674).
This might sometimes fail if there is a timezone change, but TIO uses UTC, so there it should work.
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~167~~ 164 bytes
-3 bytes thanks to ceilingcat.
```
r;P(n,i){for(r=0;++i<n;)r|=n%i<1;}f(y,m,d){for(;P(y+m+d,1),r;)d=--d?d:" >8><><>><><>"[!--m?y--,m=12:m]/2+(m==2&y%4<1&y%100|y%400<1);printf("%04d-%02d-%02d",y,m,d);}
```
[Try it online!](https://tio.run/##bVBBboMwEDyHV7iWqIywVdslJY4h@ULvVQ8VBsTBJKJpVZTwdrq2SZtKFdpdz87OrE3F2qqa50E/k552ybk5DGQouU7Truh1MlzKPu4KoaeGjNRSEyZgekxtaqhI6KATUzJm9maL0W6zK@DzCb/cMWb3I2PUlkJu7euDTIktS3k/xlkhIAvOL3DmvBCJPg5df2oIjnlmWMxlSJiGvXqaPw@dQS2BKTRS5IoNxYRSL916adcmic7R6n9fROqvY12dur5Ff5lkizB1G8AGnJ2rcwQ3Ha3cb/CEA8eP0zvBGI5TFPn7vHU98UtbghAS9DdukJO2RKgsB7ShSKwhAoKQ6yu/BiQ4dDPHO4QU8PnC5/lTUHj@BgUeKQXTQoa4QTzwkgvYjUAluYsrEj/7ncLf2KmU2gS9VAv/KNS1A9Ujv9@9b5q/AQ "C (gcc) – Try It Online")
## Rundown
```
r;P(n,i){for(r=0;++i<n;)r|=n%i<1;}
```
The anti-prime-checking function. Since the earliest valid year we need to deal with is 0001-01-01, the lowest number we ever need to worry about is 3, so the special-case checks for n==2 or n < 2 are stripped out. r is set to a truthy value if n is *not* a prime. r is kept global, since not having to return it saves two bytes (`i=n;` to return vs `,r` to check the global). i is set to 1 by the function caller, to save another 2 bytes.
```
f(y,m,d){for(;P(y+m+d,1),r;)
```
We take the date as three separate integers and start the main loop, which goes on until y+m+d is prime. Then we come to the meat of the function:
```
!--d?                           Decrement day and check if zero, which means we go back to last day of previous month.
d=" >8><><>><><>"               The string contains the number of days of each month times 2, to bring them into printable ASCII range.
                                We begin the string with a space, to avoid having to substract from index later.
[!--m?y--,m=12:m]/2+            Decrement month and check if zero. If so, go back a year and set m to 12. Use m as index in string.
(m==2&!(y%4)&y%100|!(y%400))    If the new month is February, add 1 to day if it's a leap year.
:0;                             Do nothing if day did not become zero.
```
It might seem iffy to use m and y both in the leap year check and as the index of the string, when the evaluation order is unspecified. Luckily, we only check for leap year if m == 2, which can't happen at the same time as we change m and y, since that only happens going from January to December, so the leap year check is never bothered by the order of evaluation.
Finally, the result is printed to STDOUT:
```
printf("%04d-%02d-%02d",y,m,d);}
```
[Answer]
# C# - ~~281~~ ~~239~~ 232 Char
```
using System;class P{static void Main(){var d=DateTime.Parse(Console.ReadLine());do{int c=d.Year+d.Month+d.Day;if(c%2!=0){int i=3;for(;i<=c;i+=2)if(c%i==0)break;if(i>=c)break;}d=d.AddDays(-1);}while(d>DateTime.MinValue);Console.WriteLine(d);}}
```
ungolfed:
```
using System;
class P
{
    static void Main()
    {
        var d = DateTime.Parse(Console.ReadLine());
        do
        {
            int c = d.Year + d.Month + d.Day;
            // minimum datetime in c# is 0001-01-01
            // therefore do not need to check for the first two primes 
            int i = 3;
            for (; i < c; i += 2) if (c % i == 0) break;
            // check to break the date decrement loop if counter passed the input value
            // ie, no factor could be found
            if (i >= c) break;
            d = d.AddDays(-1);
        } while (d > DateTime.MinValue);
        Console.WriteLine(d);
    }
}
```
Made the code less efficient but smaller. Prime loop will now go up to the integer rather than the square root. It will also process all even numbers.
[Answer]
# [MATL](https://github.com/lmendo/MATL), 14 bytes
```
`tsZp?.}YOqZOT
```
[Try it online!](https://tio.run/##JYuxDkBAEER7XzFfILvnWFtp9NdokEvoSQitbz/rJFO8yZvZ13tLS1ruazq68hnDOYUhxdgPaWb1ghZcx8K4FjCB/FdEGpD8RVXBzmLsiFtQA0f5YoYY9BmuOM@cxhc "MATL – Try It Online")
Alternately:
### 15 bytes
```
`tsZp~tbYOw-ZOw
```
[Try it online!](https://tio.run/##JYsxCoAwEAR7X7EfEO6i5nK9vY2NSkCtFQQD6fx6TBS2mGV2zy0caU1ruOfrCfs0xHoeYvL9mBbWVuDAna8ydwImUFuKiAXJX1QVbHIyG2IHsjD0XbIhBhXDDX8zo/4F "MATL – Try It Online")
[Answer]
# Scala, 116 bytes
```
d=>LazyList.iterate(d)(_ minusDays 1)find{d=>val s=d.getYear+d.getMonthValue+d.getDayOfMonth
2 to s/2 forall(s%_>0)}
```
Uses `java.time.LocalDate` as input and output.
[Try it in Scastie](https://scastie.scala-lang.org/JgawE0wBTPG4EmI8UcE6JQ)
]