Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Saving a list into a json with DateTime as a Header

Discussion in 'Scripting' started by slaga, Aug 19, 2021.

  1. slaga

    slaga

    Joined:
    Dec 3, 2018
    Posts:
    142
    i don't know if I'm explaining it right but what i want is to be able to save 3 lists of strings but have them separated based on time. The idea is to store some strings for each day and save them into a json so i can search for the date and display them into a calendar.

    My try was like so
    Code (CSharp):
    1.  
    2. [Serializable]
    3. public class TimeStamp
    4. {
    5.    public string CreatedDate;
    6.    public List<Entries> day = new List<Entries>();
    7. }
    8.  
    9. [Serializable]
    10. public class Entries
    11. {
    12.    public List<string> names = new List<string>();
    13.    public List<string> location = new List<string>();
    14.    public List<string> info = new List<string>();
    15. }
    which then i saved like so

    Code (CSharp):
    1.  string json = JsonUtility.ToJson(timeStamp);
    2.        try
    3.        {
    4.            timeStamp.CreatedDate = DateTime.UtcNow.ToLocalTime().ToString("dd-MM-yyyy   HH:mm");
    5.            File.WriteAllText(Application.persistentDataPath + "/Journal.json", json);
    6.            Debug.Log("Data Saved");
    7.        }
    8.  
    9.        catch (Exception e)
    10.        {
    11.            Debug.Log("Error Saving Data:" + e);
    12.            throw;
    13.        }
    Which does save everything i need but its not separated by the date, trying to explain it the way i think of it is that i want the date to be the "header" of the Json so in one Json file i would have all entries for each day and also i made them into a list so i can add or remove strings.

    So later on when i want to add something i would search for the date and access the names list for instance and .Add() my string to that list

    In a rather crude way this is how i would like my json to look like:

    Code (CSharp):
    1. entries
    2. [
    3.    "date"[
    4.           list1 = []
    5.           list2 = []
    6.           list3 = []
    7.         ]      
    8. ]
    The way i feel like it should be is something like this
    Code (CSharp):
    1.  
    2. [Serializable]
    3. public class Roots
    4. {
    5.    public TimeStamp timeStamp;
    6. }
    7.  
    8. [Serializable]
    9. public class TimeStamp
    10. {
    11.    public List<Entries> entries;
    12. }
    13.  
    14. [Serializable]
    15. public class Entries
    16. {
    17.    public List<string> names = new List<string>();
    18.    public List<string> location = new List<string>();
    19.    public List<string> info = new List<string>();
    20. }
    which gives a json like this
    Code (CSharp):
    1.  
    2. {
    3.   "Entries": {
    4.    "Timestamp": [ // this entry here //
    5.      {
    6.        "names": "",
    7.        "location": "",
    8.        "info": ""
    9.      }
    10.    ]
    11.   }
    12. }
    but how can i make that Timestamp be a string or a date?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    System.DateTime can help you with almost all time / date needs, including formatting.

    Problems with Unity "tiny lite" built-in JSON:

    In general I highly suggest staying away from Unity's JSON "tiny lite" package. It's really not very capable at all and will silently fail on very common data structures, such as Dictionaries and Hashes and ALL properties.

    Instead grab Newtonsoft JSON .NET off the asset store for free, or else install it from the Unity Package Manager (Window -> Package Manager).

    https://forum.unity.com/threads/jso...-not-working-as-expected.722783/#post-4824743

    https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347

    Also, always be sure to leverage sites like:

    https://jsonlint.com
    https://json2csharp.com
    https://csharp2json.io

    PS: for folks howling about how NewtonSoft JSON .NET will "add too much size" to your game, JSON .NET is like 307k in size, and it has the important advantage that it actually works the way you expect a JSON serializer to work in the year 2021.
     
  3. slaga

    slaga

    Joined:
    Dec 3, 2018
    Posts:
    142
    thank you for the reply , i ended up working it like this

    Code (CSharp):
    1. [Serializable]
    2. public class Roots
    3. {
    4.     public int dayCount = -1;
    5.     public List<TimeStamp> timeStamps;
    6. }
    7.  
    8. [Serializable]
    9. public class TimeStamp
    10. {
    11.     public string CreatedDate = DateTime.UtcNow.ToLocalTime().ToString("dd-MM-yyyy   HH:mm");
    12.     public Entries day;
    13. }
    14.  
    15. [Serializable]
    16. public class Entries
    17. {
    18.     public List<string> name = new List<string>();
    19.     public List<string> location = new List<string>();
    20.     public List<string> info = new List<string>();
    21. }
    22.  
    23. public class JournalData : MonoBehaviour
    24. {
    25.     [SerializeField] private Roots root;
    26.     public Roots Roots { get => root; }
    27.  
    28.  
    29.     public void ChangeDay()
    30.     {
    31.         root.dayCount++;
    32.         root.timeStamps.Add(new TimeStamp());
    33.     }
    34.  
    35.     void AddToList()
    36.     {
    37.         root.timeStamps[root.dayCount].day.name.Add("John");
    38.     }
    39.  
    40.  
    41.     public void Save()
    42.     {
    43.         string json = JsonUtility.ToJson(root);
    44.         try
    45.         {
    46.             File.WriteAllText(Application.persistentDataPath + "/Journal.json", json);
    47.             Debug.Log("Data Saved");
    48.         }
    49.  
    50.         catch (Exception e)
    51.         {
    52.             Debug.Log("Error Saving Data:" + e);
    53.             throw;
    54.         }
    55.      
    56.     }
    57.  
    58.     public void Load()
    59.     {
    60.         try
    61.         {
    62.             string userString = File.ReadAllText(Application.persistentDataPath + "/Journal.json");
    63.  
    64.             Roots rootData = JsonUtility.FromJson<Roots>(userString);
    65.          
    66.             if (rootData != null)
    67.             {
    68.                 root.dayCount = rootData.dayCount;
    69.                 root.timeStamps = rootData.timeStamps;
    70.             }
    71.          
    72.             Debug.Log("Data Loaded");
    73.         }
    74.         catch (Exception e)
    75.         {
    76.             Debug.Log("Error Loading Data:" + e);
    77.             throw;
    78.         }
    79.     }
    80.  
    81. }
    82.  
    which generates this JSON

    Code (CSharp):
    1. {
    2.     "dayCount": 0,
    3.     "timeStamps": [
    4.         {
    5.             "CreatedDate": "20-08-2021   13:14",
    6.             "day": {
    7.                 "name": [
    8.                     "John"
    9.                 ],
    10.                 "location": [],
    11.                 "info": []
    12.             }
    13.         }
    14.     ]
    15. }
    but since its obvious you know more about it than me what do you think of this way? is it good or should i switch to newtonsoft and let that handle things?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    If it works, ship it!

    If you understand the limitations and Unity's JSON Lite still solves your problem, go with what you have. Just know when it will stop working.