1

I have a task to split a time string in UTC format (e.g. 2021-06-16T00:29:01Z) into a year, month and day. Since the UTC format assumes a constant string length, I wanted to assign values to variables in a certain memory range through the assembler. Is it possible? The code below returns an empty string for some reason

function boo(string memory _string) public view returns (string memory result) {
        assembly {
            result := mload(add(_string, 64))
        }
    }
}

1 Answer 1

1

Strings in memory have 32 bytes at the beginning that are the length followed by the string's data.

Doing something like this will leave the ascii representation of the year, month, day in the first bytes of each variable.

function parseDate(string memory date) public pure returns (bytes32, bytes32, bytes32) {
    // Expected format yyyy-mm-dd
    bytes32 year;
    bytes32 month;
    bytes32 day;
    assembly {
        let x := mload(add(date, 32))
        year  := shl(224, shr(224, x))     // 28 * 8
        x     := mload(add(date, 37))      // 32 + 4 + 1
        month := shl(240, shr(240, x))     // 30 * 8
        x     := mload(add(date, 40))      // 32 + 4 + 1 + 2 + 1
        day   := shl(240, shr(240, x))
    }
    return (year, month, day);
}

You still have to do the conversion from ascii to decimal so doing all of this in assembly seems like a pointless exercise.

There's a solidity library to deal with strings, perhaps it is something you may want to take a look at https://github.com/Arachnid/solidity-stringutils.

1
  • Thanks A LOT. I needed this answer
    – Nikita Rov
    Aug 20, 2021 at 18:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.