Avatar billede steen_hansen Forsker
22. februar 2022 - 18:46 Der er 7 kommentarer og
3 løsninger

Split dato

Jeg har en del problemer med at "omrokere" på datoformatet inden det skal gemmes i MySQL. Der skal omrokeres, så det gemmes i

YYYY-MM-DD

i stedet for

DD-MM-YYYY

https://bytes.com/topic/asp-classic/answers/544544-split-convert-date-question har jeg fundet noget, som umiddelbart ligger lige til højrebenet, men den giver hele tiden denne fejl:

Microsoft VBScript runtime error '800a0009'

Subscript out of range: '[number: 1]'

Og det skyldes denne linie:

        result(1) = temp(1)

Jeg søgte på Microsoft's sider, og fandt dette, som umiddelbart ikke gjorde mig meget klogere, udover at der kan være noget uoverensstemmelse i indexet i arrayet ............


MIN SIDE (meget forenklet)
-------------------------------------------------------------------------------------------------
<html>

<%
    Function changeUserDate(userDate)
        Dim result(3)
        temp = Split(userDate,"/")
        result(2) = temp(0)
        result(1) = temp(1)
        result(0) = temp(2)
        changeUserDate = Join(result,"-")
    End Function

    If Request("mode") = "createnewbulletin" Then
        Dim removemessage
        removemessage = changeUserDate(Request.Form("ChooseDate"))

    Conn.Execute("INSERT INTO messages (removeat) VALUES ("removemessage")")
%>

<body>

<%
    Dim ChooseDato, FirstOfThisMonth, FirstOfNextMonth, FirstOfNextNextMonth
    ChooseDato = date()
    FirstOfThisMonth = DateAdd("d", -day(ChooseDato) + 1, ChooseDato)
    FirstOfNextMonth = DateAdd("m", 1, FirstOfThisMonth)
    FirstOfNextNextMonth = DateAdd("m", 2, FirstOfThisMonth)
%>

<input type="radio" name="ChooseDate" id="ChooseDate2" value="<%=FirstOfNextMonth%>" class="mb-1"><label for "ChooseDate2" class="offset-sm-03"><%=FirstOfNextMonth%> - Med dette valg fjernes din besked om <%=FirstOfNextMonth - date()%><% If FirstOfNextNextMonth - date() > 1 Then %> dage<% Else %> dag<% End If %> klokken 00:15</label>

<form>
<input type="radio" name="ChooseDate" id="ChooseDate3" value="<%=FirstOfNextNextMonth%>" class="mb-1"><label for "ChooseDate3" class="offset-sm-03"><%=FirstOfNextNextMonth%> - Med dette valg fjernes din besked om <%=FirstOfNextNextMonth - date()%><% If FirstOfNextNextMonth - date() > 1 Then %> dage<% Else %> dag<% End If %> klokken 00:15</label>
</form>

</body>
</html>

Men der er åbenbart noget galt med den function. Jeg har forsøgt at rette op og ned på

        result(2) = temp(0)
        result(1) = temp(1)
        result(0) = temp(2)

Håber der er en med et godt kendskab
Avatar billede erikjacobsen Ekspert
22. februar 2022 - 19:18 #1
temp = Split(userDate,"/")  virker når datoen er 11/11/1111
men når du har 11-11-1111 skal du vel:

          temp = Split(userDate,"-")
Avatar billede claes57 Ekspert
22. februar 2022 - 19:50 #2
man kunne trave userDate igennem tegn for tegn og erstatte alt, der ikke er isnumeric med / og så derefter temp = Split(userDate,"/")
evt også teste på at hvis det foregående tegn ikke var numerisk, og det aktuelle heller ikke er, så bare videre til næste tegn, så der ikke kommer 22///2/2022
til sidst ( lige før Split(userDate,"/") ) så test på isdate() - er det ikke en dato, så lav en fejlmelding, eller bare spring posten over.
Avatar billede arne_v Ekspert
22. februar 2022 - 20:49 #3
Tja.

Erik har jo helt ret i at der skal splittes på det rigtige tegn.

Med hensyn til at gøre koden lidt mere robust med hensyn til forskellige tegn så var det nok ret oplgat at bruge regex til at splitte med.

Men grundliggende er det en forkert tilgang til at gemme datoer i en database - det bør bruges parameters, så giver man bare et Date objekt og ADO (ADO provider) sørger for at håndtere det korrekt.
Avatar billede steen_hansen Forsker
25. februar 2022 - 14:27 #4
@arne_v: Jeg har brugt de sidste dage på at finde en løsning. Jeg faldt over en, som var rendt ind i det samme problem på stackoverflow. Han blev også tilrådet at benytte RegEx, og her var der en bruger, der fejlrettede et problem ved at benytte regex i stedet for split

Ham tog jeg fat i, og spurgte om han kunne hjælpe. Han virkede utrolig kompetent, men måtte give op. Men han foreslog at lave en split af dato v.hj.a. en function

Function changeUserDate(userDate)
        Dim result(3)
        temp = Split(userDate, "/")
        changeUserDate = temp(2) & "-" & temp(1) & "-" & temp(0)
End Function

removemessage = changeUserDate(Request.Form("ChooseDate"))

Men han kunne ikke se hvad variablen dækker over, som jeg fandt på https://bytes.com/topic/asp-classic/answers/544544-split-convert-date-question

Kan du finde ud af hvordan? Jeg håber du kan. Jeg har snart brugt oceaner af tid på dette her
Avatar billede steen_hansen Forsker
25. februar 2022 - 14:36 #5
<html>

<%
    Function changeUserDate(userDate)
        Dim result(3)
        temp = Split(userDate, "/")
        changeUserDate = temp(2) & "-" & temp(1) & "-" & temp(0)
    End Function

    If Request("mode") = "createnewbulletin" Then

        Dim RS
        Set RS = Conn.Execute("SELECT username, bulletinboard FROM count")
        If Not RS.EOF Then
            Do Until RS.EOF
                RSAddOne = RS("bulletinboard") + CInt(1)
                Conn.Execute("UPDATE count SET bulletinboard = " & RSAddOne & " WHERE username = '" & RS("username") & "'")
            RS.MoveNext
            Loop
        End If

        Dim dato, author, headline, message, removemessage
        dato = Day(Date) & "/" & Month(Date) & "/" & Year(Date) & " " & Time()
        author = SQLEncode(Session("username"))
        headline = Request.Form("headline")
        message = Request.Form("vMessage")

        'Dim rmm() As String
        'rmm = Split(removemessage, "-")
        'removemessage = rmm(2) & "-" & rmm(1) & "-"; rmm(0)
        'Debug.Print(Request.Form("ChooseDate"))

        removemessage = changeUserDate(Request.Form("ChooseDate"))

        Conn.Execute("INSERT INTO messages (dato, author, headline, message, removeat) VALUES (" & _
            "'" & dato & "', " & _
            "'" & author & "', " & _
            "'" & Trim(SQLEncode(Request.Form("headline"))) & "', " & _
            "'" & SQLEncode(Request.Form("vMessage")) & "', " & _
            "'" & removemessage & "')")
        Conn.Close

        Response.Redirect("/dk/bulletinboard/")
    End If
%>


<body>
                                            <form action="/dk/profile/bulletin_new/" name="frmNewBulletin" id="frmNewBulletin" method="post">
                                            <input type="hidden" name="mode" value="createnewbulletin">
                                                <div class="form-group my-0 row">
                                                    <div class="col-md-3 text-right mt-1">
                                                        Overskrift
                                                    </div>
                                                    <div class="col-md-9">
                                                        <input type="text" name="headline" class="w-100" autofocus>
                                                    </div>
                                                </div>
                                                <div class="form-group my-0 row">
                                                    <div class="col-md-3 text-right mt-1">
                                                        <label class="h4">Besked</label>
                                                    </div>
                                                    <div class="col-md-9">
                                                        <textarea class="mh-15 w-100" name="vMessage" required="required"></textarea>
                                                    </div>
                                                </div>
                                                <div class="form-group my-0 row mt-5">
                                                    <div class="col-md-3 text-right mb-1">
                                                        <label class="h4">Din hilsen</label>
                                                    </div>
                                                    <div class="col-md-9">
                                                        <p><strong>Med venlig hilsen</strong></p>
                                                        <p><strong><%=Session("username")%></strong></p>
                                                    </div>
                                                </div>
                                                <div class="form-group my-0 row">
                                                    <div class="col-md-3 text-right mt-1">
                                                        <label class="h4">Beskeden skal fjernes den</label>
                                                    </div>
                                                    <div class="col-md-9 mt-1">
                                                        <input type="radio" name="ChooseDate" id="ChooseDate1" value="<%=date()+1%>" class="mb-1" checked><label for "ChooseDate1" class="offset-sm-03"><%=date()+1%> - Med dette valg fjernes din besked i nat klokken 00:15</label>
                                                    </div>
                                                    <div class="col-md-3 text-right">
                                                        &nbsp;
                                                    </div>
                                                    <div class="col-md-9">
                                                    <%
                                                        Dim ChooseDato, FirstOfThisMonth, FirstOfNextMonth, FirstOfNextNextMonth
                                                        ChooseDato = date()
                                                        FirstOfThisMonth = DateAdd("d", -day(ChooseDato) + 1, ChooseDato)
                                                        FirstOfNextMonth = DateAdd("m", 1, FirstOfThisMonth)
                                                        FirstOfNextNextMonth = DateAdd("m", 2, FirstOfThisMonth)
                                                    %>
                                                        <input type="radio" name="ChooseDate" id="ChooseDate2" value="<%=FirstOfNextMonth%>" class="mb-1"><label for "ChooseDate2" class="offset-sm-03"><%=FirstOfNextMonth%> - Med dette valg fjernes din besked om <%=FirstOfNextMonth - date()%><% If FirstOfNextNextMonth - date() > 1 Then %> dage<% Else %> dag<% End If %> klokken 00:15</label>
                                                    </div>
                                                    <div class="col-md-3 text-right">
                                                        &nbsp;
                                                    </div>
                                                    <div class="col-md-9 mt-1">
                                                        <input type="radio" name="ChooseDate" id="ChooseDate3" value="<%=FirstOfNextNextMonth%>" class="mb-1"><label for "ChooseDate3" class="offset-sm-03"><%=FirstOfNextNextMonth%> - Med dette valg fjernes din besked om <%=FirstOfNextNextMonth - date()%><% If FirstOfNextNextMonth - date() > 1 Then %> dage<% Else %> dag<% End If %> klokken 00:15</label>
                                                    </div>
                                                </div>
                                                <div class="form-group my-0 row">
                                                    <div class="col-md-3 text-right mt-1">
                                                        &nbsp;
                                                    </div>
                                                    <div class="col-md-9">
                                                        <input type="submit" class="btn btn-primary btn-block btn-lg" value="Opret besked">
                                                    </div>
                                                </div>
                                            </form>

</body>
</html>
Avatar billede arne_v Ekspert
25. februar 2022 - 15:24 #6
En klog mand inden for IT har engang sagt at tricket til bedre forståelse er ikke at indsamle mest mulig information men at smide mest mulig information der ikke skal bruges væk.

Så hvad er kernen i problemet her?

1) Du har en variabel af type streng med en dato i format dd-mm-yyy eller dd/mm/yyyy og skal have konverteret til et Date objekt.
2) Du har et Date objekt som skal indsættes i et felt af typen DATE i din MySQL database.

Eller??

Hvis vi forstår problemet præcist kan vi nemt finde en løsning.
Avatar billede steen_hansen Forsker
25. februar 2022 - 19:59 #7
Jeg har 3 variabler, som brugerne kan vælge imellem. Brugeren kan vælge, om indlægget skal fjernes

1. i nat klokken 00:15
2. den 01-03-2022
3. eller den 01-04-2022

Efter den første marts gælder
1. i nat klokken 00:15
2. den 01-04-2022 klokken 00:15
3. eller den 01-05-2022 klokken 00:15

Osv.

Jeg sætter et cron-job i sving hver nat klokken 00:15, som sletter de indlæg, hvor udløbsdato = indeværende dato

I databasen bliver det gemt i yyyy-mm-dd
Det ovenstående smider ikke en dato ned i DB, men 0000-00-00. Måske fordi der gemmes som dd-mm-yyyy, og da formattet skal leveres som yyyy-mm-dd, så lægges der blot 0'er ned?

A. Derfor er jeg begyndt at kigge efter noget, som kan få det korrekt. Jeg er ude efter noget, som kan bearbejdes alt efter hvilket sprog OS benytter. På arbejde er det et amerikansk firma vi er ansat i, med engelsksproget Windows/browsere på alle arbejds-PC'ere.

B. Jeg er på udkig efter noget, hvor jeg udvikle noget på danske platforme, hvor datoformatet bliver vist korrekt. Og her tror jeg allerede dit eksempel med ADO virker, af en eller anden årsag. Hvis jeg begynder at trække den kundevalgte fra udløbsdatoen, nedtælles dagene fint nok.

C. Jeg er også ved at udvikle for noget familie jeg har i Thailand, og her skal datoerne selvfølgelig også beregnes korrekt. Jeg antager, at det skal gøres i engelsk format. Men den tid, den glæde. Hvis jeg kan mestre det her dato-halløj, er det jo "bare" at tilpasse formatet efter behov.

Ja, man skal smide den information, som man ikke har brug for, væk. Det er helt korrekt. Men jeg fægter lidt i blinde her. Det er derfor jeg gik i gang med at undersøge, læste noget på én side, som blev modargumenteret på en anden. Og pludselig er forvirringen total. Jeg håber du har noget brugbart.
Avatar billede steen_hansen Forsker
25. februar 2022 - 20:39 #8
PS: Jeg har indsat Session.LCID = 1030 i toppen af alle sider. Er det engelsk, skal det selvfølgelig ændres til engelsk
Avatar billede arne_v Ekspert
27. februar 2022 - 02:27 #9
Jeg mener stadigvæk at den rette strategi er:
- fortæl brugeren hvilket dato format der skal anvendes f.eks. dd/mm/yyyy
- hvis du selv viser dato så bruger du samme format f.eks. dd/mm/yyyy
- ved form submit konverterer du streng til Date object
- du gemmer i databasen med parameters
- når du henter far databasen og skal vise dato så konverterer du Date objekt tilbage til streng

Kode:

<%
INVALIDDATE = DateSerial(0, 0, 0)
adParamInput = 1
adInteger = 3
adDate = 7

' argument : string, expected format dd/mm/yyyy or dd-mm-yyyy or dd.mm.yyyy
' return  : Date object, possible INVALIDDATE
function String2Date(s)
    Set reo = New RegExp
    reo.Pattern = "(\d{2})[/\-\.](\d{2})[/\-\.](\d{4})"
    reo.Global = True
    Set mco = reo.Execute(s)
    if mco.Count = 1 then
        Set mo = mco.Item(0)
        dd = mo.SubMatches(0)
        mm = mo.SubMatches(1)
        yyyy = mo.SubMatches(2)
        d = CInt(dd)
        m = CInt(mm)
        y = CInt(yyyy)
        if 1 <= d and d <= 31 and 1 <= m and m <= 12 and 2000 <= y and y <= 2050 then
            res = DateSerial(y, m, d)
        else
            res = INVALIDDATE
        end if
    else
        res = INVALIDDATE
    end if
    Set mo = Nothing
    Set mco = Nothing
    Set reo = Nothing
    String2Date = res
end function

' argument : Date object
' return  : satring in format dd/mm/yyyy
function Date2String(dt)
    d = Day(dt)
    m = Month(dt)
    y = Year(dt)
    dd = CStr(d)
    if Len(dd) = 1 then dd = "0" & dd
    mm = CStr(m)
    if Len(mm) = 1 then mm = "0" & mm
    yyyy = CStr(y)                                                                           
    Date2String = dd & "/" & mm & "/" & yyyy
end function

' test String2Date and Date2String
sub test(s)
    d = String2Date(s)
    if d <> INVALIDDATE then
        Response.Write s & " -> " + Date2String(d) & "<br>"
    else
        Response.Write s & " is not a valid date<br>"
    end if
end sub

call test("26/02/2022")
call test("26-02-2022")
call test("26.02.2022")
call test("33/02/2022")
call test("2022-02-26")
call test("123")
call test("ABC")

' insert Date objects in database using parameters and select again from database
Set con = Server.CreateObject("ADODB.Connection")
con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Work\Database11.accdb;User Id=admin;Password=;"
Set ins = Server.CreateObject("ADODB.Command")
ins.ActiveConnection = con
ins.CommandText = "INSERT INTO dtest VALUES(@i,@d)"
ins.Parameters.Append(ins.CreateParameter("@i", adInteger, adParamInput))
ins.Parameters.Append(ins.CreateParameter("@d", adDate, adParamInput))
ins.Parameters("@i").Value = 1
ins.Parameters("@d").Value = String2Date("21/02/2022")
ins.Execute
ins.Parameters("@i").Value = 2
ins.Parameters("@d").Value = String2Date("22/02/2022")
ins.Execute
ins.Parameters("@i").Value = 3
ins.Parameters("@d").Value = String2Date("23/02/2022")
ins.Execute
Set ins = Nothing
Set sel = Server.CreateObject("ADODB.Command")
sel.ActiveConnection = con
sel.CommandText = "SELECT * FROM dtest"
Set rs = sel.Execute
Do While Not rs.EOF
    Response.Write rs("i") & " " & Date2String(rs("d")) & "<br>"
    rs.MoveNext
Loop
Set rs = Nothing
Set sel = Nothing
Set con = Nothing

%>
Avatar billede steen_hansen Forsker
21. marts 2022 - 20:05 #10
@arne_v Jeg har valgt at benytte <input type="date"> og smide det ned i et recordset af typen date. Det fungerer perfekt. Og så må brugerne finde sig i at der bliver ændret i datovalg. Det er bedre, hvis de selv vælger en dato. Den dato kan trækkes ud, lægge  antal dage fra eller til. Det fungerer bare godt :) Tak for hjælpen, Arne

@claes57 @erikjacobsen Tak for hjælpen :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester